Skip to content

Commit 2cd2277

Browse files
authored
implement real XOR chance logic (replaces old, which is renamed FIRST) (#3187)
1 parent e78d1d6 commit 2cd2277

4 files changed

Lines changed: 89 additions & 1 deletion

File tree

src/generated/resources/assets/gtceu/lang/en_ud.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,7 @@
21642164
"gtceu.canner": "ɹǝuuɐƆ",
21652165
"gtceu.centrifuge": "ǝbnɟıɹʇuǝƆ",
21662166
"gtceu.chance_logic.and": "ᗡNⱯ",
2167+
"gtceu.chance_logic.first": "⟘SᴚIℲ",
21672168
"gtceu.chance_logic.none": "ƎNON",
21682169
"gtceu.chance_logic.or": "ᴚO",
21692170
"gtceu.chance_logic.xor": "ᴚOX",

src/generated/resources/assets/gtceu/lang/en_us.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,7 @@
21642164
"gtceu.canner": "Canner",
21652165
"gtceu.centrifuge": "Centrifuge",
21662166
"gtceu.chance_logic.and": "AND",
2167+
"gtceu.chance_logic.first": "FIRST",
21672168
"gtceu.chance_logic.none": "NONE",
21682169
"gtceu.chance_logic.or": "OR",
21692170
"gtceu.chance_logic.xor": "XOR",

src/main/java/com/gregtechceu/gtceu/api/recipe/chance/logic/ChanceLogic.java

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
import net.minecraftforge.fml.ModLoader;
1111

1212
import com.google.common.collect.ImmutableList;
13+
import it.unimi.dsi.fastutil.ints.IntArrayList;
14+
import it.unimi.dsi.fastutil.ints.IntList;
1315
import it.unimi.dsi.fastutil.objects.Object2IntMap;
1416
import org.jetbrains.annotations.ApiStatus;
1517
import org.jetbrains.annotations.NotNull;
1618
import org.jetbrains.annotations.Nullable;
1719
import org.jetbrains.annotations.Unmodifiable;
1820

21+
import java.util.ArrayList;
1922
import java.util.Collections;
2023
import java.util.List;
2124

@@ -115,7 +118,7 @@ public String toString() {
115118
/**
116119
* Chanced Output Logic where only the first ingredient succeeding its roll will be produced
117120
*/
118-
public static final ChanceLogic XOR = new ChanceLogic("xor") {
121+
public static final ChanceLogic FIRST = new ChanceLogic("first") {
119122

120123
@Override
121124
public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries,
@@ -141,6 +144,88 @@ public String toString() {
141144
return builder.build();
142145
}
143146

147+
@Override
148+
public @NotNull Component getTranslation() {
149+
return Component.translatable("gtceu.chance_logic.first");
150+
}
151+
152+
@Override
153+
public String toString() {
154+
return "ChanceLogic{FIRST}";
155+
}
156+
};
157+
158+
/**
159+
* Chanced Output Logic where only one of the ingredients will be output, in a manner weighted to the input chances
160+
*/
161+
public static final ChanceLogic XOR = new ChanceLogic("xor") {
162+
163+
@Override
164+
public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries,
165+
@NotNull ChanceBoostFunction boostFunction,
166+
int recipeTier, int chanceTier,
167+
@Nullable Object2IntMap<?> cache, int times) {
168+
// Have to set up a system where all chances are set to be out of 10000
169+
IntList chancesOutOfTenThousand = new IntArrayList();
170+
171+
for (Content orig : chancedEntries) {
172+
if (orig.maxChance == getMaxChancedValue()) {
173+
chancesOutOfTenThousand.add(orig.chance);
174+
} else {
175+
chancesOutOfTenThousand.add((int) ((orig.chance / (float) orig.maxChance) * getMaxChancedValue()));
176+
}
177+
}
178+
179+
int chanceTotal = 0;
180+
for (int chance : chancesOutOfTenThousand) {
181+
chanceTotal += chance;
182+
}
183+
184+
// Here, if the newly calculated chances don't add up to 10000, they're renormalized
185+
if (chanceTotal != getMaxChancedValue()) {
186+
int chanceTotalDecremented = getMaxChancedValue();
187+
for (int i = 0; i < chancesOutOfTenThousand.size(); i++) {
188+
int newChance = (int) (chancesOutOfTenThousand.getInt(i) *
189+
((float) getMaxChancedValue() / (float) chanceTotal));
190+
// last chance ends up being set to the remainder in case things don't line up
191+
if (i == chancesOutOfTenThousand.size() - 1) {
192+
chancesOutOfTenThousand.set(i, chanceTotalDecremented);
193+
} else {
194+
chancesOutOfTenThousand.set(i, newChance);
195+
}
196+
chanceTotalDecremented -= newChance;
197+
}
198+
}
199+
200+
// Finally, generate a new Content list with the changes
201+
List<Content> normalizedEntries = new ArrayList<>();
202+
for (int i = 0; i < chancesOutOfTenThousand.size(); i++) {
203+
normalizedEntries.add(new Content(chancedEntries.get(i).content, chancesOutOfTenThousand.getInt(i),
204+
getMaxChancedValue(), chancedEntries.get(i).tierChanceBoost));
205+
}
206+
207+
// Use the new, normalized list for the logic
208+
ImmutableList.Builder<Content> builder = ImmutableList.builder();
209+
for (int i = 0; i < times; ++i) {
210+
Content selected = null;
211+
int maxChance = getMaxChancedValue();
212+
for (Content entry : normalizedEntries) {
213+
int newChance = getChance(entry, boostFunction, recipeTier, chanceTier);
214+
int cached = getCachedChance(entry, cache);
215+
int chance = newChance + cached;
216+
if (passesChance(chance, maxChance)) {
217+
selected = entry;
218+
newChance -= maxChance;
219+
}
220+
updateCachedChance(entry.content, cache, newChance / 2 + cached);
221+
if (selected != null) break;
222+
maxChance -= newChance;
223+
}
224+
if (selected != null) builder.add(selected);
225+
}
226+
return builder.build();
227+
}
228+
144229
@Override
145230
public @NotNull Component getTranslation() {
146231
return Component.translatable("gtceu.chance_logic.xor");

src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,7 @@ public static void init(RegistrateLangProvider provider) {
13281328
provider.add("gtceu.chance_logic.or", "OR");
13291329
provider.add("gtceu.chance_logic.and", "AND");
13301330
provider.add("gtceu.chance_logic.xor", "XOR");
1331+
provider.add("gtceu.chance_logic.first", "FIRST");
13311332
provider.add("gtceu.chance_logic.none", "NONE");
13321333

13331334
provider.add("gtceu.gui.content.per_tick", "§aConsumed/Produced Per Tick§r");

0 commit comments

Comments
 (0)