diff --git a/src/main/java/emu/nebula/data/custom/CharGemAttrGroupDef.java b/src/main/java/emu/nebula/data/custom/CharGemAttrGroupDef.java index 1329240..c543476 100644 --- a/src/main/java/emu/nebula/data/custom/CharGemAttrGroupDef.java +++ b/src/main/java/emu/nebula/data/custom/CharGemAttrGroupDef.java @@ -7,6 +7,7 @@ import emu.nebula.data.BaseDef; import emu.nebula.data.GameData; import emu.nebula.data.ResourceType; import emu.nebula.data.resources.CharGemAttrValueDef; +import emu.nebula.game.character.GameCharacter; import emu.nebula.util.WeightedList; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; @@ -42,7 +43,7 @@ public class CharGemAttrGroupDef extends BaseDef { return this.uniqueAttrNum.next(); } - public CharGemAttrTypeData getRandomAttributeType(IntList list) { + public CharGemAttrTypeData getRandomAttributeType(GameCharacter character, IntList list) { // Setup blacklist to prevent the same attribute from showing up twice var blacklist = new IntOpenHashSet(); @@ -58,13 +59,23 @@ public class CharGemAttrGroupDef extends BaseDef { var random = new WeightedList(); for (var type : this.getAttributeTypes()) { + // Don't add types that we already have in the emblem if (blacklist.contains(type.getId())) { continue; } + // Skip attributes that don't match the trekker's element + if (type.isElementalAttr() && !character.getElementType().getGemAttrTypes().contains(type.getFirstSubType())) { + continue; + } + random.add(100, type); } + if (random.size() == 0) { + return null; + } + return random.next(); } @@ -91,6 +102,7 @@ public class CharGemAttrGroupDef extends BaseDef { @Getter public static class CharGemAttrTypeData { private int id; + private int firstSubType; private WeightedList values; public CharGemAttrTypeData(int id) { @@ -98,7 +110,12 @@ public class CharGemAttrGroupDef extends BaseDef { this.values = new WeightedList<>(); } + public boolean isElementalAttr() { + return this.getFirstSubType() >= 17 && this.getFirstSubType() <= 28; + } + public void addValue(CharGemAttrValueDef value) { + this.firstSubType = value.getAttrTypeFirstSubtype(); this.values.add(value.getRarity(), value); } diff --git a/src/main/java/emu/nebula/data/resources/CharGemAttrValueDef.java b/src/main/java/emu/nebula/data/resources/CharGemAttrValueDef.java index 08e2aa7..b4365e1 100644 --- a/src/main/java/emu/nebula/data/resources/CharGemAttrValueDef.java +++ b/src/main/java/emu/nebula/data/resources/CharGemAttrValueDef.java @@ -12,6 +12,7 @@ public class CharGemAttrValueDef extends BaseDef { private int Id; private int TypeId; private int AttrType; + private int AttrTypeFirstSubtype; private int Rarity; @Override diff --git a/src/main/java/emu/nebula/data/resources/CharGemSlotControlDef.java b/src/main/java/emu/nebula/data/resources/CharGemSlotControlDef.java index b705158..6bd8899 100644 --- a/src/main/java/emu/nebula/data/resources/CharGemSlotControlDef.java +++ b/src/main/java/emu/nebula/data/resources/CharGemSlotControlDef.java @@ -4,6 +4,7 @@ import emu.nebula.data.BaseDef; import emu.nebula.data.GameData; import emu.nebula.data.ResourceType; import emu.nebula.data.custom.CharGemAttrGroupDef; +import emu.nebula.game.character.GameCharacter; import emu.nebula.util.Utils; import emu.nebula.util.WeightedList; import emu.nebula.util.ints.CustomIntArray; @@ -35,8 +36,8 @@ public class CharGemSlotControlDef extends BaseDef { return Id; } - public IntList generateAttributes() { - return this.generateAttributes(new CustomIntArray()); + public IntList generateAttributes(GameCharacter character) { + return this.generateAttributes(character, new CustomIntArray()); } // Check if we should add unique attributes based on the probablity @@ -45,14 +46,18 @@ public class CharGemSlotControlDef extends BaseDef { return random <= this.UniqueAttrGroupProb; } - public IntList generateAttributes(CustomIntArray list) { + public IntList generateAttributes(GameCharacter character, CustomIntArray list) { // Add unique attributes if (this.UniqueAttrGroupId > 0 && this.shouldAddUniqueAttr()) { var group = GameData.getCharGemAttrGroupDataTable().get(this.UniqueAttrGroupId); int num = group.getRandomUniqueAttrNum(); for (int i = 0; i < num; i++) { - var attributeType = group.getRandomAttributeType(list); + var attributeType = group.getRandomAttributeType(character, list); + if (attributeType == null) { + break; + } + list.add(attributeType.getRandomValue()); } @@ -76,7 +81,8 @@ public class CharGemSlotControlDef extends BaseDef { // Add up to 4 attributes while (list.getValueCount() < this.MaxAlterNum) { var group = random.next(); - var attributeType = group.getRandomAttributeType(list); + var attributeType = group.getRandomAttributeType(character, list); + list.add(attributeType.getRandomValue()); } diff --git a/src/main/java/emu/nebula/game/character/ElementType.java b/src/main/java/emu/nebula/game/character/ElementType.java index 1852ddb..4ac1d68 100644 --- a/src/main/java/emu/nebula/game/character/ElementType.java +++ b/src/main/java/emu/nebula/game/character/ElementType.java @@ -1,22 +1,28 @@ package emu.nebula.game.character; +import java.util.Arrays; + import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import lombok.Getter; @Getter public enum ElementType { INHERIT (0), - AQUA (1, 90018), - FIRE (2, 90019), - EARTH (3, 90021), - WIND (4, 90020), - LIGHT (5, 90022), - DARK (6, 90023), + AQUA (1, 90018, new int[] {17, 23}), + FIRE (2, 90019, new int[] {18, 24}), + EARTH (3, 90021, new int[] {19, 25}), + WIND (4, 90020, new int[] {20, 26}), + LIGHT (5, 90022, new int[] {21, 27}), + DARK (6, 90023, new int[] {22, 28}), NONE (7); private final int value; private final int subNoteSkillItemId; + private final IntSet gemAttrTypes; + private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); static { @@ -26,12 +32,15 @@ public enum ElementType { } private ElementType(int value) { - this(value, 0); + this(value, 0, new int[0]); } - private ElementType(int value, int subNoteSkillItemId) { + private ElementType(int value, int subNoteSkillItemId, int[] attrTypes) { this.value = value; this.subNoteSkillItemId = subNoteSkillItemId; + + this.gemAttrTypes = new IntOpenHashSet(); + Arrays.stream(attrTypes).forEach(this.gemAttrTypes::add); } public static ElementType getByValue(int value) { diff --git a/src/main/java/emu/nebula/game/character/GameCharacter.java b/src/main/java/emu/nebula/game/character/GameCharacter.java index 39040d7..cec9cfe 100644 --- a/src/main/java/emu/nebula/game/character/GameCharacter.java +++ b/src/main/java/emu/nebula/game/character/GameCharacter.java @@ -698,7 +698,7 @@ public class GameCharacter implements GameDatabaseObject { } // Generate attributes and create gem - var attributes = gemControl.generateAttributes(); + var attributes = gemControl.generateAttributes(this); var gem = new CharacterGem(attributes); // Add gem to slot @@ -771,7 +771,7 @@ public class GameCharacter implements GameDatabaseObject { } // Generate attributes and create gem - var attributes = gemControl.generateAttributes(list); + var attributes = gemControl.generateAttributes(this, list); gem.setNewAttributes(attributes); // Save to database