├── GiveArtifactPlugin.jar
├── .idea
├── vcs.xml
├── .gitignore
├── discord.xml
└── misc.xml
├── src
└── main
│ ├── resources
│ └── plugin.json
│ └── java
│ └── snoobi
│ └── bignose
│ ├── GiveArtifactSnoo.java
│ └── commands
│ └── GiveArtCommand.java
├── .gitignore
├── README.md
└── pom.xml
/GiveArtifactPlugin.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/snoobi-seggs/GiveArtifactPlugin/HEAD/GiveArtifactPlugin.jar
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/discord.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/main/resources/plugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GiveArtifactSnoo",
3 | "description": "A simple command plugins that simplifies the shit artifact giving system in GC",
4 | "version": "1.3.1",
5 | "authors": [ "snoobiXorange" ],
6 |
7 | "mainClass": "snoobi.bignose.GiveArtifactSnoo",
8 |
9 | "comments": [
10 | "ew kira is cringe"
11 | ]
12 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Store
39 |
40 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main/java/snoobi/bignose/GiveArtifactSnoo.java:
--------------------------------------------------------------------------------
1 | package snoobi.bignose;
2 |
3 | import emu.grasscutter.plugin.Plugin;
4 | import snoobi.bignose.commands.GiveArtCommand;
5 |
6 | public final class GiveArtifactSnoo extends Plugin {
7 | /* Turn the plugin into a singleton. */
8 | private static GiveArtifactSnoo instance;
9 |
10 | public static GiveArtifactSnoo getInstance() {
11 | return instance;
12 | }
13 |
14 | @Override public void onLoad() {
15 | // Set the plugin instance.
16 | instance = this;
17 | }
18 |
19 | @Override public void onEnable() {
20 | // Register commands.
21 | this.getHandle().registerCommand(new GiveArtCommand());
22 |
23 | // Log a plugin status message.
24 | this.getLogger().info("The Give Artifact plugin has been enabled.");
25 | }
26 |
27 | @Override public void onDisable() {
28 | // Log a plugin status message.
29 | this.getLogger().info("The GiveArt plugin died lol");
30 | }
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Give Artifact Plugin
2 | idk why this wasnt done ages ago and ever since exzork arti website died i have been sad.
3 | its simple as frick to understand, almost impossible to screw up.
4 |
5 | ## Basics of this plugin
6 |
7 | ### Calling
8 |
9 | -> `/ga` or `/giveartifact` or `/gart' to call this command
10 |
11 | ### Usage
12 |
13 | -> `/ga [artifactId] [mainstatName] [substatName]=[substatValue] [level]`
14 |
15 | -> creates an artifact from the given details
16 |
17 | -> (% are 1 - 100) so cdmg=7.8 is 7.8% of crit damage
18 |
19 | -> eg `/ga 21543 hp% cr=23.4 cdmg=46.7 def=55 cdr=100 21`
20 | -> `21543` => `Gilded Dreams Flower` [required]
21 | -> `hp%` => `mainstat name` [not required]
22 | -> `cr` => `substat1 name` [not required]
23 | -> `23.4` => `substat1 value` [not required]
24 |
25 | -> `etc...`
26 |
27 | -> `21` => `artifact level (1-21)` [not required, defaut is max]
28 |
29 | -> `godset function not available yet`
30 |
31 | -> DO NOT USE WITH TAMILPP RESOURCES FOR NOW AS THE AFFIX STATS ARE OUTDATED
32 |
33 | ### Download
34 |
35 | -> Proceed to `Releases` and download `GiveArtifactPlugMyAss.jar`
36 |
37 | -> Place this jar file in ur plugins folder for gc
38 |
39 |
40 |
41 | ### Version
42 | This Plugin supports Grasscutter version `1.2.3 - latest version (i hope)`.
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | snoobiXorange
8 | GiveArtifactSnoo
9 | 1.2.3
10 |
11 |
12 | 17
13 | 17
14 |
15 |
16 |
17 |
21 |
22 | sonatype
23 | https://s01.oss.sonatype.org/content/groups/public/
24 |
25 |
26 |
27 |
28 |
29 | xyz.grasscutters
30 | grasscutter
31 | 1.2.3
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/java/snoobi/bignose/commands/GiveArtCommand.java:
--------------------------------------------------------------------------------
1 | package snoobi.bignose.commands;
2 |
3 | import emu.grasscutter.command.Command;
4 | import emu.grasscutter.command.CommandHandler;
5 | import emu.grasscutter.data.GameData;
6 | import emu.grasscutter.data.excels.ItemData;
7 | import emu.grasscutter.game.inventory.GameItem;
8 | import emu.grasscutter.game.inventory.ItemType;
9 | import emu.grasscutter.game.player.Player;
10 | import emu.grasscutter.game.props.ActionReason;
11 |
12 | import emu.grasscutter.data.excels.ReliquaryAffixData;
13 | import emu.grasscutter.data.excels.ReliquaryMainPropData;
14 | import emu.grasscutter.game.props.FightProperty;
15 |
16 | import java.util.*;
17 | import static java.util.Map.entry;
18 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
19 |
20 | @Command(label = "giveart", usage = "/ga [] [=] []\n\nmainstatNames:\n [hp,hp%,atk,atk%,def,def%,er,em,hb,cdmg,cr,phys,dendro,geo,hydro,anemo,cryo,electro,pyro]\n\nsubstatnames:\n[cdr,same as the ones above,speed,dmg,sb]", aliases = {"ga","giveartifact","gart"}, permission = "player.giveart", permissionTargeted = "player.giveart.others", targetRequirement = Command.TargetRequirement.NONE)
21 | public final class GiveArtCommand implements CommandHandler {
22 |
23 | //maps substat actual names to maps of id and substatvalue
24 | Map> substatMap;// = loadSubstats();
25 |
26 | //maps substat typable names to substat actual names
27 | private static final Map substatNameMap = Map.ofEntries(
28 | entry("hp", "FIGHT_PROP_HP"),
29 | entry("healthpoint","FIGHT_PROP_HP"),
30 | entry("healthpoints","FIGHT_PROP_HP"),
31 | entry("hp%", "FIGHT_PROP_HP_PERCENT"),
32 | entry("hppercentage","FIGHT_PROP_HP_PERCENT"),
33 | entry("atk", "FIGHT_PROP_ATTACK"),
34 | entry("attack","FIGHT_PROP_ATTACK"),
35 | entry("atk%", "FIGHT_PROP_ATTACK_PERCENT"),
36 | entry("attackpercent","FIGHT_PROP_ATTACK_PERCENT"),
37 | entry("attackpercentage","FIGHT_PROP_ATTACK_PERCENT"),
38 | entry("def", "FIGHT_PROP_DEFENSE"),
39 | entry("defense","FIGHT_PROP_DEFENSE"),
40 | entry("defence","FIGHT_PROP_DEFENSE"),
41 | entry("def%", "FIGHT_PROP_DEFENSE_PERCENT"),
42 | entry("defensepercent","FIGHT_PROP_DEFENSE_PERCENT"),
43 | entry("defencepercent","FIGHT_PROP_DEFENSE_PERCENT"),
44 | entry("defensepercentage","FIGHT_PROP_DEFENSE_PERCENT"),
45 | entry("defencepercentage","FIGHT_PROP_DEFENSE_PERCENT"),
46 | entry("er", "FIGHT_PROP_CHARGE_EFFICIENCY"),
47 | entry("energyrecharge","FIGHT_PROP_CHARGE_EFFICIENCY"),
48 | entry("em", "FIGHT_PROP_ELEMENT_MASTERY"),
49 | entry("elementalmastery","FIGHT_PROP_ELEMENT_MASTERY"),
50 | entry("cr", "FIGHT_PROP_CRITICAL"),
51 | entry("crate","FIGHT_PROP_CRITICAL"),
52 | entry("critrate","FIGHT_PROP_CRITICAL"),
53 | entry("criticalrate","FIGHT_PROP_CRITICAL"),
54 | entry("cdmg", "FIGHT_PROP_CRITICAL_HURT"),
55 | entry("critdmg","FIGHT_PROP_CRITICAL_HURT"),
56 | entry("critdamage","FIGHT_PROP_CRITICAL_HURT"),
57 | entry("criticaldmg","FIGHT_PROP_CRITICAL_HURT"),
58 | entry("criticaldamage","FIGHT_PROP_CRITICAL_HURT"),
59 | entry("cd","FIGHT_PROP_CRITICAL_HURT"),
60 | entry("cdr","FIGHT_PROP_SKILL_CD_MINUS_RATIO"),
61 | entry("cdreduction","FIGHT_PROP_SKILL_CD_MINUS_RATIO"),
62 | entry("cooldownreduction","FIGHT_PROP_SKILL_CD_MINUS_RATIO"),
63 | entry("phys","FIGHT_PROP_PHYSICAL_ADD_HURT"),
64 | entry("dendro","FIGHT_PROP_GRASS_ADD_HURT"),
65 | entry("geo","FIGHT_PROP_ROCK_ADD_HURT"),
66 | entry("anemo","FIGHT_PROP_WIND_ADD_HURT"),
67 | entry("hydro","FIGHT_PROP_WATER_ADD_HURT"),
68 | entry("cryo","FIGHT_PROP_ICE_ADD_HURT"),
69 | entry("electro","FIGHT_PROP_ELEC_ADD_HURT"),
70 | entry("pyro","FIGHT_PROP_FIRE_ADD_HURT"),
71 | entry("hb","FIGHT_PROP_HEAL_ADD"),
72 | entry("speed","FIGHT_PROP_SPEED_PERCENT"),
73 | entry("sb","FIGHT_PROP_SHIELD_COST_MINUS_RATIO"),
74 | entry("shieldbonus","FIGHT_PROP_SHIELD_COST_MINUS_RATIO"),
75 | entry("shield","FIGHT_PROP_SHIELD_COST_MINUS_RATIO"),
76 | entry("damage","FIGHT_PROP_SUB_HURT"),
77 | entry("dr","FIGHT_PROP_SUB_HURT"),
78 | entry("dmgr","FIGHT_PROP_SUB_HURT"),
79 | entry("dmgreduction","FIGHT_PROP_SUB_HURT"),
80 | entry("damagereduction","FIGHT_PROP_SUB_HURT"),
81 | entry("damager","FIGHT_PROP_SUB_HURT")
82 | );
83 |
84 | //maps mainstat actual names to maps of id
85 | Map mainstatMap;// = loadMainStats();
86 |
87 | //maps mainstat typable names to mainstat actual names
88 | private static final Map mainstatNameMap = Map.ofEntries(
89 | entry("hp","FIGHT_PROP_HP"),
90 | entry("hp%","FIGHT_PROP_HP_PERCENT"),
91 | entry("atk","FIGHT_PROP_ATTACK"),
92 | entry("atk%","FIGHT_PROP_ATTACK_PERCENT"),
93 | entry("def","FIGHT_PROP_DEFENSE"),
94 | entry("def%","FIGHT_PROP_DEFENSE_PERCENT"),
95 | entry("er","FIGHT_PROP_CHARGE_EFFICIENCY"),
96 | entry("em","FIGHT_PROP_ELEMENT_MASTERY"),
97 | entry("hb","FIGHT_PROP_HEAL_ADD"),
98 | entry("cdmg","FIGHT_PROP_CRITICAL_HURT"),
99 | entry("cd","FIGHT_PROP_CRITICAL_HURT"),
100 | entry("cr","FIGHT_PROP_CRITICAL"),
101 | entry("phys","FIGHT_PROP_PHYSICAL_ADD_HURT"),
102 | entry("dendro","FIGHT_PROP_GRASS_ADD_HURT"),
103 | entry("geo","FIGHT_PROP_ROCK_ADD_HURT"),
104 | entry("anemo","FIGHT_PROP_WIND_ADD_HURT"),
105 | entry("hydro","FIGHT_PROP_WATER_ADD_HURT"),
106 | entry("cryo","FIGHT_PROP_ICE_ADD_HURT"),
107 | entry("electro","FIGHT_PROP_ELEC_ADD_HURT"),
108 | entry("pyro","FIGHT_PROP_FIRE_ADD_HURT")
109 | );
110 |
111 | //gets mainstat from mainstat name to id map
112 | private int getMainstatId(String mainstatName, Map mainstatMap) {
113 | if (!mainstatNameMap.containsKey(mainstatName)) {
114 | return 0;
115 | } else {
116 | return mainstatMap.get(mainstatNameMap.get(mainstatName));
117 | }
118 | }
119 |
120 | //gets the closest roll with the given substat name with the remaining substat value left, returning the closest roll id and value of it
121 | private List getSubstatIdClosestRoll(String substatName,String substatValue, Map> substatMap) {
122 | float value;
123 |
124 | if (!substatNameMap.containsKey(substatName)) {
125 | return List.of(0,0f);
126 | }
127 |
128 | //catch non float type substat
129 | try {
130 | value = Float.parseFloat(substatValue);
131 | }
132 | catch (NumberFormatException e) {
133 | return List.of(0,0f);
134 | }
135 |
136 | int closestId = 0;
137 | float closestValue = 0f;
138 | for (Map.Entry entry: substatMap.get(substatNameMap.get(substatName)).entrySet()) {
139 | if (entry.getValue() < value && entry.getValue() > closestValue) { //iterrates to get the max value that is smaller than parsed stats
140 | closestId = entry.getKey();
141 | closestValue = entry.getValue();
142 | } else {
143 | ;
144 | }
145 | }
146 | //returns in [int,float]
147 | return List.of(closestId,closestValue);
148 | }
149 |
150 |
151 |
152 | @Override
153 | public void execute(Player sender, Player targetPlayer, List args) {
154 | // Sanity check
155 | if (targetPlayer == null) {
156 | targetPlayer = sender;
157 | }
158 |
159 | //mainstatmap formation
160 | Map mainstatMap = new HashMap();
161 | for (Map.Entry entry : GameData.getReliquaryMainPropDataMap().entrySet()) {
162 | mainstatMap.put(entry.getValue().getFightProp().toString(),entry.getKey());
163 | }
164 |
165 | //substatmap formation
166 | Map> substatMap = new HashMap>();
167 | Int2ObjectMap loadSubstatMap = GameData.getReliquaryAffixDataMap();
168 | for (Map.Entry entry2 : loadSubstatMap.entrySet()) {
169 | if (substatMap.get(entry2.getValue().getFightProp().toString()) != null) {
170 | Map temp = substatMap.get(entry2.getValue().getFightProp().toString());
171 | temp.put(entry2.getValue().getId(),entry2.getValue().getPropValue());
172 | substatMap.remove(entry2.getValue().getFightProp().toString());
173 | substatMap.put(entry2.getValue().getFightProp().toString(),temp);
174 |
175 | } else {
176 | Map map = new HashMap<>();
177 | map.put(entry2.getValue().getId(),entry2.getValue().getPropValue());
178 | substatMap.put(entry2.getValue().getFightProp().toString(),map);
179 | }
180 | }
181 |
182 |
183 | // satanise or send usage
184 | if (args.size() < 1) {
185 | CommandHandler.sendMessage(sender,"All artifacts have a unique id of:\n[N1] [N2] [N3] [N4] [N5] 5numbers\n\n[N1][N2] -> ArtifactSet ID\n[N3] -> 1/2/3/4/5 for [N3] star arti\n[N4] -> 1/2/3/4/5\n goblet/plume/circlet/flower/sands\n[N5] -> number of substats 1-4(not needed as the stats are fixed later)\n\nSET IDs:\n20 -> Deepwood Memories\n21 -> Gilded Dreams\n71 -> Blizzard Strayer\n72 -> Thunder Soother\n73 -> Lavawalker\n74 -> Maiden's Beloved\n75 -> Gladiator's Finale\n76 -> Veridescent Venerer\n77 -> Wanderer's Troupe\n78 -> Glacier and Snoofield\n79 -> Thundering Fury\n80 -> Crimson Bitch Of Flames\n81 -> Noblesse Oblige\n82 -> Bloodstained Chilvary\n88 -> Archaic Petra\n89 -> Retracing Bolide\n90 -> Heart of Depth\n91 -> Tenacity of the Millelith\n92 -> Pale Flame\n93 -> Shimenawa's Reminiscence\n94 -> Emblem of Severed Fate\n95 -> Husk of Opulent Dreams\n96 -> Ocean's Hued Clam\n97 -> Vermillion Hereafter\n98 -> Echoes of the Offering\n99 -> UNKNOWN");
186 | String availableMainstats = "[";
187 | for (Map.Entry entry : mainstatNameMap.entrySet()) {
188 | availableMainstats = availableMainstats + entry.getKey() + ", ";
189 | } availableMainstats += "]";
190 | String availableSubstats = "[hp, healthpoint, healthpoints, hp%, hppercentage, atk, attack, atk%, attackpercent, attackpercentage, def, defense, defence, def%, defensepercent, defencepercent, defensepercentage, defencepercentage, er, energyrecharge, em, elementalmastery, cr, crate, critrate, criticalrate, cdmg, critdmg, critdamage, criticaldmg, criticaldamage, cd, cdr, cdreduction, cooldownreduction, phys, dendro, geo, anemo, hydro, cryo, electro, pyro, hb, speed, sb, shieldbonus, shield, dr, dmgr, dmgreduction, damagereduction, damager]";
191 | CommandHandler.sendMessage(sender, "mainstats:\n" + availableMainstats + "\n\nsubstats:\n" + availableSubstats);
192 | CommandHandler.sendMessage(sender, "/ga [] [=] []");
193 | return;
194 | }
195 |
196 | // Get the artifact piece ID from the arguments.
197 | int itemId;
198 |
199 | try {
200 | itemId = Integer.parseInt(args.remove(0)); //not an itemId at all
201 | } catch (NumberFormatException ignored) {
202 | CommandHandler.sendMessage(sender, "this itemId does not belong to an artifact");
203 | return;
204 | }
205 |
206 | ItemData itemData = GameData.getItemDataMap().get(itemId); //not an artifact
207 | if (itemData != null) {
208 | if (itemData.getItemType() != ItemType.ITEM_RELIQUARY) {
209 | CommandHandler.sendMessage(sender, "this itemId does not belong to an artifact");
210 | return;
211 | }
212 | } else {
213 | CommandHandler.sendMessage(sender, "This is not even a valid item wtf, can u type properly thanks.");
214 | return;
215 | }
216 |
217 | // Get the main stat name from the arguments, and remove it
218 | String mainstatIdString = "";
219 | try {
220 | String temp = args.get(0); // test the waters
221 | //incase have substat no mainstat, thus skip
222 | if (temp.split(",").length == 2 || temp.split("=").length == 2) {
223 | mainstatIdString = "0";
224 | } else {
225 | mainstatIdString = args.remove(0);
226 | }
227 | } catch (IndexOutOfBoundsException e) {
228 | mainstatIdString = "0";
229 | }
230 | int mainstatId = 0; // allows for no mainstat at all
231 |
232 | // Convert this main stat name to id by retrieving from mainpropmap
233 | if (mainstatIdString.equals("0")) {
234 | CommandHandler.sendMessage(sender,"you did not input a mainstat,thus it is set to NONE");
235 | } else if (getMainstatId(mainstatIdString, mainstatMap) != 0) {
236 | mainstatId = getMainstatId(mainstatIdString, mainstatMap);
237 | } else {
238 | CommandHandler.sendMessage(sender,"This main stat does not exist, generating artifact with no mainstat"); // allows no mainstat
239 | }
240 |
241 | // Get the level from the arguments.
242 | int level = 21; // default 21 for retards who dont know how to specify this
243 | try {
244 | int lastArgument = Integer.parseInt(args.get(args.size()-1));
245 | if (lastArgument > 0 && lastArgument < 22) { // Luckily appendPropIds aren't in the range of [1,21]
246 | level = lastArgument;
247 | args.remove(args.size()-1);
248 | } else {
249 | CommandHandler.sendMessage(sender,"No level specified, auto set to level 20");
250 | }
251 | } catch (NumberFormatException ignored) { // Could be a statname roll once,times string so no need to panic
252 | CommandHandler.sendMessage(sender,"No level specified, auto set to level 20");
253 | } catch (IndexOutOfBoundsException e) { // could be a dumb fuck who dont know how type numbers
254 | CommandHandler.sendMessage(sender,"No level specified, auto set to level 20");
255 | }
256 |
257 | // Get substats from parems.
258 | ArrayList substatIdList = new ArrayList<>();
259 |
260 | try {
261 | // Every remaining argument is a substat.
262 | args.forEach(statWithValue -> {
263 | // Split the string into substatName and substatValue if that is the case here.
264 | String[] arr;
265 | String substatName = "";
266 | String remainder;
267 | List statInfo;
268 |
269 | //splits and check stats to add to substatlist
270 | if ((arr = statWithValue.split(",")).length == 2 || (arr = statWithValue.split("=")).length == 2) {
271 | if (substatNameMap.get(arr[0]) != null) {
272 | substatName = arr[0];
273 | } else {
274 | CommandHandler.sendMessage(sender, "this substatname is invalid");
275 | arr[1] = "0";
276 | }
277 | //makes sure that % arent 100 times of what it shld be [hp,atk,def,em]
278 | if (Float.parseFloat(arr[1]) > 0) {
279 | if (substatNameMap.get(substatName).equals("FIGHT_PROP_HP") || substatNameMap.get(substatName).equals("FIGHT_PROP_DEFENSE") || substatNameMap.get(substatName).equals("FIGHT_PROP_ATTACK") || substatNameMap.get(substatName).equals("FIGHT_PROP_ELEMENT_MASTERY")) { // dont need to divide 100, the rest of stats are all in %
280 | remainder = arr[1];
281 | } else {
282 | remainder = String.valueOf( (Float.parseFloat(arr[1]) + 0.1f) / 100);
283 | }
284 | } else {
285 | remainder = "0"; //ignorestats neg(-)
286 | CommandHandler.sendMessage(sender, "The stat inputted " + arr[0] + " was below 0, which doesnt make sense, so the stat will be ignored");
287 | }
288 | //adds substats to substatlist until remainder is 0
289 | while (Float.parseFloat(remainder) >= 0f && !getSubstatIdClosestRoll(substatName, remainder, substatMap).equals(List.of(0,0f))) {
290 | statInfo = getSubstatIdClosestRoll(substatName, remainder, substatMap);
291 | substatIdList.add(Integer.parseInt(statInfo.get(0).toString()));
292 | remainder = String.valueOf((Float.parseFloat(remainder) - Float.parseFloat(statInfo.get(1).toString())));
293 | }
294 | } else {
295 | CommandHandler.sendMessage(sender,"mistyped stat value for " + statWithValue + ",this ignoring it");
296 | }
297 | });
298 | } catch (NumberFormatException e) {
299 | CommandHandler.sendMessage(sender, "substat value for one of the inputted substats do not have a numerical value, thus this substat is ignored");
300 | } catch (IllegalArgumentException e) {
301 | CommandHandler.sendMessage(sender,"type a valid substat value for frick sake");
302 | return;
303 | } catch (Exception e) {
304 | CommandHandler.sendMessage(sender,e.toString() + ".\nomg error occured, please open an issue in the github page and report it there thanks:]"); //catch unknown error for now debug
305 | }
306 |
307 | //check if empty for substats coz why not
308 | if (substatIdList.size() == 0) {
309 | CommandHandler.sendMessage(sender, "this artifact has no substats since u didnt specify them at all, for some reason");
310 | }
311 |
312 | // Create item for the artifact.
313 | GameItem item = new GameItem(itemData);
314 | item.setLevel(level);
315 | item.setMainPropId(mainstatId);
316 | item.getAppendPropIdList().clear();
317 | item.getAppendPropIdList().addAll(substatIdList);
318 | targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop);
319 |
320 | //shows mainstat in string format
321 | String finalMainstatInString = "NONE";
322 | if (mainstatId != 0) {
323 | finalMainstatInString = GameData.getReliquaryMainPropDataMap().get(mainstatId).getFightProp().toString();
324 | }
325 | //calculates stats added
326 | List