65public class ItemDefinition {
71 private static final Map<FightType, Integer> EMPTY =
new HashMap<>();
72 public static final ItemDefinition DEFAULT =
new ItemDefinition(1,
"null");
75 private final String name;
76 private String destroyMessage;
77 private boolean destroyable;
78 private boolean stackable;
79 private boolean twoHanded;
80 private boolean tradeable;
81 private int stand_animation;
82 private int attack_anim;
83 private int walk_animation;
84 private int run_animation;
85 private Map<FightType, Integer> attack_animations;
86 private int block_animation;
87 private int unnotedId;
89 private int street_value;
90 private int base_value;
93 private double weight;
97 private int[] requirements;
98 private int[] bonuses;
100 public ItemDefinition(
int id, String name) {
103 this.destroyMessage =
null;
104 this.destroyable =
false;
105 this.stackable =
false;
106 this.tradeable =
true;
107 this.twoHanded =
false;
110 this.street_value = 0;
118 this.attack_animations = EMPTY;
119 this.block_animation = -1;
121 this.weaponInterface =
null;
122 this.rangedDefinition =
null;
123 this.requirements = EMPTY_REQUIREMENTS;
124 this.bonuses = EMPTY_BONUSES;
128 return new GsonParser(
"def/item/item_definitions",
false) {
131 public void initialize(
int size) {
136 protected void parse(JsonObject data) {
137 int id = data.
get(
"id").getAsInt();
138 String name = data.get(
"name").getAsString();
142 if (data.has(
"destroyable")) {
143 definition.destroyable = data.get(
"destroyable").getAsBoolean();
146 if (data.has(
"destroy-message")) {
147 definition.destroyable =
true;
148 definition.destroyMessage = data.get(
"destroy-message").getAsString();
151 if (data.has(
"stackable")) {
152 definition.stackable = data.get(
"stackable").getAsBoolean();
155 if (data.has(
"tradeable")) {
156 definition.tradeable = data.get(
"tradeable").getAsBoolean();
159 if (data.has(
"two-handed")) {
160 definition.twoHanded = data.get(
"two-handed").getAsBoolean();
163 if (data.has(
"noted-id")) {
164 definition.notedId = data.get(
"noted-id").getAsInt();
167 if (data.has(
"unnoted-id")) {
168 definition.unnotedId = data.get(
"unnoted-id").getAsInt();
171 if (data.has(
"street-value")) {
172 definition.street_value = data.get(
"street-value").getAsInt();
175 if (data.has(
"base-value")) {
176 definition.base_value = data.get(
"base-value").getAsInt();
179 if (data.has(
"high-alch")) {
180 definition.highAlch = data.get(
"high-alch").getAsInt();
183 if (data.has(
"low-alch")) {
184 definition.lowAlch = data.get(
"low-alch").getAsInt();
187 if (data.has(
"weight")) {
188 definition.weight = data.get(
"weight").getAsDouble();
191 if (data.has(
"equipment-slot")) {
192 definition.equipmentType = EquipmentType.valueOf(data.get(
"equipment-slot").getAsString());
195 if (data.has(
"weapon-interface")) {
196 definition.weaponInterface = WeaponInterface.valueOf(data.get(
"weapon-interface").getAsString());
199 for (
int index = 0; index < SKILL_REQUIREMENT_CONFIG_FIELD_NAMES.length; index++) {
200 String skillRequirement = SKILL_REQUIREMENT_CONFIG_FIELD_NAMES[index];
201 if (data.has(skillRequirement)) {
202 if (definition.requirements == EMPTY_REQUIREMENTS) {
203 definition.requirements =
new int[EMPTY_REQUIREMENTS.length];
205 definition.requirements[index] = data.get(skillRequirement).getAsInt();
209 for (
int index = 0; index < BONUS_CONFIG_FIELD_NAMES.length; index++) {
210 String bonusName = BONUS_CONFIG_FIELD_NAMES[index];
211 if (data.has(bonusName)) {
212 if (definition.bonuses == EMPTY_BONUSES) {
213 definition.bonuses =
new int[EMPTY_BONUSES.length];
215 definition.bonuses[index] = data.get(bonusName).getAsInt();
219 if (data.has(
"ranged-type") && data.has(
"allowed")) {
220 RangedWeaponType type = builder.fromJson(data.get(
"ranged-type"), RangedWeaponType.class);
221 RangedAmmunition[] allowed = builder.fromJson(data.get(
"allowed"), RangedAmmunition[].class);
222 definition.rangedDefinition =
new RangedWeaponDefinition(type, allowed);
225 if (data.has(
"stand-animation")) {
226 definition.stand_animation = data.get(
"stand-animation").getAsInt();
229 if (data.has(
"walk-animation")) {
230 definition.walk_animation = data.get(
"walk-animation").getAsInt();
233 if (data.has(
"run-animation")) {
234 definition.run_animation = data.get(
"run-animation").getAsInt();
237 if (data.has(
"attack-animations")) {
238 JsonObject
object = (JsonObject) data.get(
"attack-animations");
239 definition.attack_animations =
new HashMap<>(
object.entrySet().size());
241 for (Map.Entry<String, JsonElement> entry :
object.entrySet()) {
242 FightType fightType = FightType.valueOf(entry.getKey());
243 int animation = entry.getValue().getAsInt();
245 definition.attack_animations.put(fightType, animation);
249 if (data.has(
"block-animation")) {
250 definition.block_animation = data.get(
"block-animation").getAsInt();
257 protected void onEnd() {
258 ItemDefLoader.load();
263 public static ItemDefinition[] create(String path) {
264 ItemDefinition[] definitions =
new ItemDefinition[Config.ITEM_DEFINITION_LIMIT];
266 new GsonParser(path) {
269 public void initialize(
int size) {
270 createParser().run();
274 protected void parse(JsonObject data) {
275 int id = data.
get(
"id").getAsInt();
276 String name = data.
get(
"name").getAsString();
278 ItemDefinition definition = definitions[id] =
new ItemDefinition(
id, name);
281 if (data.has(
"destroyable")) {
282 definition.destroyable = data.get(
"destroyable").getAsBoolean();
285 if (data.has(
"destroy-message")) {
286 definition.destroyable =
true;
287 definition.destroyMessage = data.get(
"destroy-message").getAsString();
290 if (data.has(
"stackable")) {
291 definition.stackable = data.get(
"stackable").getAsBoolean();
294 if (data.has(
"tradeable")) {
295 definition.tradeable = data.get(
"tradeable").getAsBoolean();
298 if (data.has(
"two-handed")) {
299 definition.twoHanded = data.get(
"two-handed").getAsBoolean();
302 if (data.has(
"noted-id")) {
303 definition.notedId = data.get(
"noted-id").getAsInt();
306 if (data.has(
"unnoted-id")) {
307 definition.unnotedId = data.get(
"unnoted-id").getAsInt();
310 if (data.has(
"street-value")) {
311 definition.street_value = data.get(
"street-value").getAsInt();
312 }
else if (old !=
null) {
313 definition.street_value = old.street_value;
316 if (data.has(
"base-value")) {
317 definition.base_value = data.get(
"base-value").getAsInt();
320 if (data.has(
"high-alch")) {
321 definition.highAlch = data.get(
"high-alch").getAsInt();
324 if (data.has(
"low-alch")) {
325 definition.lowAlch = data.get(
"low-alch").getAsInt();
328 if (data.has(
"weight")) {
329 definition.weight = data.get(
"weight").getAsDouble();
332 if (old !=
null && old.equipmentType != EquipmentType.NOT_WIELDABLE) {
333 definition.equipmentType = old.equipmentType;
334 }
else if (data.has(
"equipment-slot")) {
335 definition.equipmentType = EquipmentType.valueOf(data.get(
"equipment-slot").getAsString());
338 for (
int index = 0; index < BONUS_CONFIG_FIELD_NAMES.length; index++) {
339 String bonusName = BONUS_CONFIG_FIELD_NAMES[index];
340 if (data.has(bonusName)) {
341 if (definition.bonuses == EMPTY_BONUSES) {
342 definition.bonuses =
new int[EMPTY_BONUSES.length];
344 definition.bonuses[index] = data.get(bonusName).getAsInt();
349 definition.weaponInterface = old.weaponInterface;
350 definition.requirements = old.requirements;
351 definition.rangedDefinition = old.rangedDefinition;
352 definition.stand_animation = old.stand_animation;
353 definition.walk_animation = old.walk_animation;
354 definition.run_animation = old.run_animation;
355 definition.attack_animations = old.attack_animations;
356 definition.block_animation = old.block_animation;
364 public static ItemDefinition[] fromClientDump(String path) {
365 ItemDefinition[] definitions =
new ItemDefinition[Config.ITEM_DEFINITION_LIMIT];
367 new GsonParser(path) {
369 protected void parse(JsonObject data) {
370 int id = data.get(
"id").getAsInt();
371 String name = data.get(
"name").getAsString();
373 ItemDefinition definition = definitions[id] =
new ItemDefinition(
id, name);
375 if (data.has(
"stackable")) {
376 definition.stackable = data.get(
"stackable").getAsBoolean();
378 if (data.has(
"destroyable")) {
379 definition.destroyable = data.get(
"destroyable").getAsBoolean();
381 if (data.has(
"noted-id")) {
382 definition.notedId = data.get(
"noted-id").getAsInt();
384 if (data.has(
"unnoted-id")) {
385 definition.unnotedId = data.get(
"unnoted-id").getAsInt();
387 if (data.has(
"base-value")) {
388 definition.base_value = data.get(
"base-value").getAsInt();
389 definition.lowAlch = (int) (definition.base_value * 0.40);
390 definition.highAlch = (int) (definition.base_value * 0.60);
392 if (data.has(
"equipment-type")) {
393 definition.equipmentType = EquipmentType.valueOf(data.get(
"equipment-type").getAsString());
401 public static void merge(String clientDumpFilePath, String wikiDumpPath, String dumpPath) {
402 new GsonParser(wikiDumpPath) {
403 LinkedListMultimap<String, JsonObject> multimap = LinkedListMultimap.create();
406 protected void parse(JsonObject data) {
407 String name = data.get(
"name").getAsString();
412 multimap.put(name, data);
416 protected void onEnd() {
417 ItemDefinition[] definitions = fromClientDump(clientDumpFilePath);
419 for (ItemDefinition definition : definitions) {
420 if (definition ==
null || definition.name.equals(
"null") || definition.name.isEmpty())
423 if (!multimap.containsKey(definition.name))
426 List<JsonObject> value = multimap.get(definition.name);
427 JsonObject
object = value.get(value.size() - 1);
429 if (value.size() > 1)
430 multimap.remove(definition.name,
object);
432 if (
object.has(
"destroy-message"))
433 definition.destroyMessage =
object.get(
"destroy-message").getAsString();
435 if (
object.has(
"tradable"))
436 definition.tradeable =
object.get(
"tradable").getAsBoolean();
438 if (
object.has(
"weight"))
439 definition.weight =
object.get(
"weight").getAsDouble();
441 if (definition.isNoted()) {
445 if (
object.has(
"two-handed"))
446 definition.twoHanded =
object.get(
"two-handed").getAsBoolean();
448 if (
object.has(
"equipment-type"))
449 definition.equipmentType = EquipmentType.valueOf(
object.
get(
"equipment-type").getAsString());
451 for (
int index = 0; index < BONUS_CONFIG_FIELD_NAMES.length; index++) {
452 String bonusName = BONUS_CONFIG_FIELD_NAMES[index];
453 if (
object.has(bonusName)) {
454 if (definition.bonuses == EMPTY_BONUSES) {
455 definition.bonuses =
new int[EMPTY_BONUSES.length];
457 definition.bonuses[index] =
object.get(bonusName).getAsInt();
469 public static void dump(ItemDefinition[] definitions, String path) {
470 JsonSaver saver =
new JsonSaver();
472 for (ItemDefinition definition : definitions) {
473 if (definition ==
null)
continue;
474 if (definition.name.equals(
"null"))
continue;
476 saver.current().addProperty(
"id", definition.id);
477 saver.current().addProperty(
"name", definition.name);
479 if (definition.destroyMessage !=
null) {
480 saver.current().addProperty(
"destroy-message", definition.destroyMessage);
481 }
else if (definition.destroyable) {
482 saver.current().addProperty(
"destroyable",
true);
485 if (definition.stackable) {
486 saver.current().addProperty(
"stackable",
true);
489 if (!definition.tradeable) {
490 saver.current().addProperty(
"tradeable",
false);
493 if (definition.twoHanded) {
494 saver.current().addProperty(
"two-handed",
true);
497 if (definition.unnotedId != definition.id) {
498 saver.current().addProperty(
"unnoted-id", definition.unnotedId);
501 if (definition.notedId != definition.id) {
502 saver.current().addProperty(
"noted-id", definition.notedId);
505 if (definition.lowAlch > 1) {
506 saver.current().addProperty(
"low-alch", definition.lowAlch);
509 if (definition.highAlch > 1) {
510 saver.current().addProperty(
"high-alch", definition.highAlch);
513 if (definition.base_value > 1) {
514 saver.current().addProperty(
"base-value", definition.base_value);
517 if (definition.street_value > 1) {
518 saver.current().addProperty(
"street-value", definition.street_value);
521 if (definition.weight != 0) {
522 saver.current().addProperty(
"weight", definition.weight);
525 if (definition.stand_animation != MobAnimation.PLAYER_STAND) {
526 saver.current().addProperty(
"stand-animation", definition.stand_animation);
529 if (definition.walk_animation != MobAnimation.PLAYER_WALK) {
530 saver.current().addProperty(
"walk-animation", definition.walk_animation);
533 if (definition.run_animation != MobAnimation.PLAYER_RUN) {
534 saver.current().addProperty(
"run-animation", definition.run_animation);
537 if (definition.attack_animations != EMPTY) {
538 saver.current().add(
"attack-animations", saver.serializer().toJsonTree(definition.attack_animations));
541 if (definition.block_animation != -1) {
542 saver.current().addProperty(
"block-animation", definition.block_animation);
545 if (definition.equipmentType != EquipmentType.NOT_WIELDABLE) {
546 saver.current().addProperty(
"equipment-slot", definition.equipmentType.name());
549 if (definition.weaponInterface !=
null && definition.weaponInterface != WeaponInterface.UNARMED) {
550 saver.current().addProperty(
"weapon-interface", definition.weaponInterface.name());
553 for (
int index = 0; index < SKILL_REQUIREMENT_CONFIG_FIELD_NAMES.length; index++) {
554 if (definition.requirements[index] > 0)
555 saver.current().addProperty(SKILL_REQUIREMENT_CONFIG_FIELD_NAMES[index], definition.requirements[index]);
558 for (
int index = 0; index < BONUS_CONFIG_FIELD_NAMES.length; index++) {
559 if (definition.bonuses[index] != 0)
560 saver.current().addProperty(BONUS_CONFIG_FIELD_NAMES[index], definition.bonuses[index]);
563 if (definition.rangedDefinition !=
null) {
564 saver.current().addProperty(
"ranged-type", definition.rangedDefinition.getType().name());
565 saver.current().add(
"allowed", saver.serializer().toJsonTree(definition.rangedDefinition.getAllowed()));
571 saver.publish(
"./data/" + path +
".json");
574 public static void dump(String path) {
575 JsonSaver saver =
new JsonSaver();
578 if (definition ==
null)
continue;
579 if (definition.name.equals(
"null"))
continue;
581 saver.current().addProperty(
"id", definition.id);
582 saver.current().addProperty(
"name", definition.name);
584 if (definition.destroyMessage !=
null) {
585 saver.current().addProperty(
"destroy-message", definition.destroyMessage);
586 }
else if (definition.destroyable) {
587 saver.current().addProperty(
"destroyable",
true);
590 if (definition.stackable) {
591 saver.current().addProperty(
"stackable",
true);
594 if (!definition.tradeable) {
595 saver.current().addProperty(
"tradeable",
false);
598 if (definition.twoHanded) {
599 saver.current().addProperty(
"two-handed",
true);
602 if (definition.unnotedId != definition.id) {
603 saver.current().addProperty(
"unnoted-id", definition.unnotedId);
606 if (definition.notedId != definition.id) {
607 saver.current().addProperty(
"noted-id", definition.notedId);
610 if (definition.lowAlch > 1) {
611 saver.current().addProperty(
"low-alch", definition.lowAlch);
614 if (definition.highAlch > 1) {
615 saver.current().addProperty(
"high-alch", definition.highAlch);
618 if (definition.base_value > 1) {
619 saver.current().addProperty(
"base-value", definition.base_value);
622 if (definition.street_value > 1) {
623 saver.current().addProperty(
"street-value", definition.street_value);
626 if (definition.weight != 0) {
627 saver.current().addProperty(
"weight", definition.weight);
630 if (definition.stand_animation != MobAnimation.PLAYER_STAND) {
631 saver.current().addProperty(
"stand-animation", definition.stand_animation);
634 if (definition.walk_animation != MobAnimation.PLAYER_WALK) {
635 saver.current().addProperty(
"walk-animation", definition.walk_animation);
638 if (definition.run_animation != MobAnimation.PLAYER_RUN) {
639 saver.current().addProperty(
"run-animation", definition.run_animation);
642 if (definition.attack_animations != EMPTY) {
643 saver.current().add(
"attack-animations", saver.serializer().toJsonTree(definition.attack_animations));
646 if (definition.block_animation != -1) {
647 saver.current().addProperty(
"block-animation", definition.block_animation);
650 if (definition.equipmentType != EquipmentType.NOT_WIELDABLE) {
651 saver.current().addProperty(
"equipment-slot", definition.equipmentType.name());
654 if (definition.weaponInterface !=
null && definition.weaponInterface != WeaponInterface.UNARMED) {
655 saver.current().addProperty(
"weapon-interface", definition.weaponInterface.name());
658 for (
int index = 0; index < SKILL_REQUIREMENT_CONFIG_FIELD_NAMES.length; index++) {
659 if (definition.requirements[index] > 0)
660 saver.current().addProperty(SKILL_REQUIREMENT_CONFIG_FIELD_NAMES[index], definition.requirements[index]);
663 for (
int index = 0; index < BONUS_CONFIG_FIELD_NAMES.length; index++) {
664 if (definition.bonuses[index] != 0)
665 saver.current().addProperty(BONUS_CONFIG_FIELD_NAMES[index], definition.bonuses[index]);
668 if (definition.rangedDefinition !=
null) {
669 saver.current().addProperty(
"ranged-type", definition.rangedDefinition.getType().name());
670 saver.current().add(
"allowed", saver.serializer().toJsonTree(definition.rangedDefinition.getAllowed()));
676 saver.publish(
"./data/" + path +
".json");
686 public static ItemDefinition
get(
int id) {
692 return DEFINITIONS[id] =
new ItemDefinition(
id,
"null");
723 return destroyMessage;
732 return unnotedId != id;
740 public boolean isNoteable() {
741 return notedId != id;
750 public int getNotedId() {
760 public int getUnnotedId() {
769 public boolean isStackable() {
778 public boolean isDestroyable() {
779 return destroyMessage !=
null;
787 public boolean isTradeable() {
796 public int getStreetValue() {
805 public int getBaseValue() {
814 public int getValue() {
815 return street_value > 0 ? street_value : base_value;
823 public int getHighAlch() {
824 return getValue() / 2;
832 public int getLowAlch() {
833 return getValue() / 5;
837 public EquipmentType getEquipmentType() {
838 return equipmentType;
841 public int[] getRequirements() {
845 public int[] getBonuses() {
854 public boolean isEquipable() {
855 return equipmentType != EquipmentType.NOT_WIELDABLE;
858 public boolean isTwoHanded() {
867 public boolean isWeapon() {
868 return EquipmentType.WEAPON.equals(equipmentType);
876 public double getWeight() {
880 public int getStandAnimation() {
881 return stand_animation;
884 public int getWalkAnimation() {
885 return walk_animation;
888 public int getRunAnimation() {
889 return run_animation;
892 public OptionalInt getAttackAnimation(FightType fightType) {
893 if (attack_animations == EMPTY) {
894 return OptionalInt.empty();
897 return OptionalInt.of(attack_animations.get(fightType));
900 public OptionalInt getBlockAnimation() {
901 return block_animation == -1 ? OptionalInt.empty() : OptionalInt.of(block_animation);
904 public Optional<RangedWeaponDefinition> getRangedDefinition() {
905 return Optional.ofNullable(rangedDefinition);
908 public WeaponInterface getWeaponInterface() {
909 return weaponInterface;
912 public void setEquipmentType(EquipmentType equipmentType) {
913 this.equipmentType = equipmentType;
916 public boolean isPotion() {
917 return this.name !=
null && (this.name.toLowerCase().contains(
"potion") || this.name.toLowerCase().contains(
"brew") ||
this.name.toLowerCase().contains(
"sanfew") ||
this.name.toLowerCase().contains(
"restore"));
920 public static ItemDefinition[] getDEFINITIONS() {
924 public static void setDEFINITIONS(ItemDefinition[]
DEFINITIONS) {
928 public void setDestroyMessage(String destroyMessage) {
929 this.destroyMessage = destroyMessage;
932 public void setDestroyable(
boolean destroyable) {
933 this.destroyable = destroyable;
936 public void setStackable(
boolean stackable) {
937 this.stackable = stackable;
940 public void setTwoHanded(
boolean twoHanded) {
941 this.twoHanded = twoHanded;
944 public void setTradeable(
boolean tradeable) {
945 this.tradeable = tradeable;
948 public int getStand_animation() {
949 return stand_animation;
952 public void setStand_animation(
int stand_animation) {
953 this.stand_animation = stand_animation;
956 public int getAttack_anim() {
960 public void setAttack_anim(
int attack_anim) {
961 this.attack_anim = attack_anim;
964 public int getWalk_animation() {
965 return walk_animation;
968 public void setWalk_animation(
int walk_animation) {
969 this.walk_animation = walk_animation;
972 public int getRun_animation() {
973 return run_animation;
976 public void setRun_animation(
int run_animation) {
977 this.run_animation = run_animation;
980 public Map<FightType, Integer> getAttack_animations() {
981 return attack_animations;
984 public void setAttack_animations(Map<FightType, Integer> attack_animations) {
985 this.attack_animations = attack_animations;
988 public int getBlock_animation() {
989 return block_animation;
992 public void setBlock_animation(
int block_animation) {
993 this.block_animation = block_animation;
996 public void setUnnotedId(
int unnotedId) {
997 this.unnotedId = unnotedId;
1000 public void setNotedId(
int notedId) {
1001 this.notedId = notedId;
1004 public int getStreet_value() {
1005 return street_value;
1008 public void setStreet_value(
int street_value) {
1009 this.street_value = street_value;
1012 public int getBase_value() {
1016 public void setBase_value(
int base_value) {
1017 this.base_value = base_value;
1020 public void setHighAlch(
int highAlch) {
1021 this.highAlch = highAlch;
1024 public void setLowAlch(
int lowAlch) {
1025 this.lowAlch = lowAlch;
1028 public void setWeight(
double weight) {
1029 this.weight = weight;
1032 public void setWeaponInterface(WeaponInterface weaponInterface) {
1033 this.weaponInterface = weaponInterface;
1036 public void setRangedDefinition(RangedWeaponDefinition rangedDefinition) {
1037 this.rangedDefinition = rangedDefinition;
1040 public void setRequirements(
int[] requirements) {
1041 this.requirements = requirements;
1044 public void setBonuses(
int[] bonuses) {
1045 this.bonuses = bonuses;