Skip to content

Commit

Permalink
Implement data based cost calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Apr 4, 2024
1 parent fb19a1a commit 97a9799
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.soulfiremc.generator.generators.BlockCollisionShapesDataGenerator;
import com.soulfiremc.generator.generators.BlocksDataGenerator;
import com.soulfiremc.generator.generators.BlocksJavaGenerator;
import com.soulfiremc.generator.generators.DefaultTagsDataGenerator;
import com.soulfiremc.generator.generators.EffectsDataGenerator;
import com.soulfiremc.generator.generators.EnchantmentsDataGenerator;
import com.soulfiremc.generator.generators.EnchantmentsJavaGenerator;
Expand Down Expand Up @@ -68,6 +69,7 @@ public class DataGenerators {
new TagsDataGenerator.BlockTagsDataGenerator(),
new TagsDataGenerator.ItemTagsDataGenerator(),
new TagsDataGenerator.EntityTypeTagsDataGenerator(),
new DefaultTagsDataGenerator(),
new WorldExporterGenerator());

private DataGenerators() {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* SoulFire
* Copyright (C) 2024 AlexProgrammerDE
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.soulfiremc.generator.generators;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonWriter;
import com.soulfiremc.generator.util.MCHelper;
import it.unimi.dsi.fastutil.ints.IntList;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Map;
import java.util.zip.GZIPOutputStream;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagNetworkSerialization;

@Slf4j
public class DefaultTagsDataGenerator implements IDataGenerator {
@Override
public String getDataName() {
return "default_tags.json.zip";
}

@SuppressWarnings("unchecked")
@SneakyThrows
@Override
public byte[] generateDataJson() {
var byteOutputStream = new ByteArrayOutputStream();
try (var gzipOutputStream = new GZIPOutputStream(byteOutputStream);
var outputStreamWriter = new OutputStreamWriter(gzipOutputStream);
var jsonWriter = new JsonWriter(outputStreamWriter)) {

var rootObj = new JsonObject();
var serialized =
TagNetworkSerialization.serializeTagsToNetwork(MCHelper.getServer().registries());

for (var entry : serialized.entrySet()) {
var registry = entry.getKey();
var payload = entry.getValue();

var registryObj = new JsonObject();

var tagsField = TagNetworkSerialization.NetworkPayload.class.getDeclaredField("tags");
tagsField.setAccessible(true);
var tags = (Map<ResourceLocation, IntList>) tagsField.get(payload);
for (var tag : tags.entrySet()) {
var tagObj = new JsonArray();

for (var id : tag.getValue()) {
tagObj.add(id);
}

registryObj.add(tag.getKey().toString(), tagObj);
}

rootObj.add(registry.location().toString(), registryObj);
}

Streams.write(rootObj, jsonWriter);

jsonWriter.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}

return byteOutputStream.toByteArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.TieredItem;
import net.minecraft.world.item.Tiers;

public class ItemsDataGenerator implements IDataGenerator {
private static List<Item> calculateItemsToRepairWith(Item sourceItem) {
Expand All @@ -48,6 +50,10 @@ public static JsonObject generateItem(Item item) {

itemDesc.addProperty("maxStackSize", item.getMaxStackSize());

if (item instanceof TieredItem tieredItem) {
itemDesc.addProperty("tierType", ((Tiers) tieredItem.getTier()).name());
}

if (item.canBeDepleted()) {
var depletionData = new JsonObject();
var repairWithItems = calculateItemsToRepairWith(item);
Expand Down
3 changes: 2 additions & 1 deletion data-generator/src/main/resources/templates/ItemType.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public record ItemType(
DepletionData depletionData,
FoodProperties foodProperties,
EquipmentSlot attributeSlot,
List<Attribute> attributes) {
List<Attribute> attributes,
TierType tierType) {
public static final Int2ReferenceMap<ItemType> FROM_ID = new Int2ReferenceOpenHashMap<>();

// VALUES REPLACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public record ItemType(
DepletionData depletionData,
FoodProperties foodProperties,
EquipmentSlot attributeSlot,
List<Attribute> attributes) {
List<Attribute> attributes,
TierType tierType) {
public static final Int2ReferenceMap<ItemType> FROM_ID = new Int2ReferenceOpenHashMap<>();

public static final ItemType AIR = register("minecraft:air");
Expand Down
54 changes: 12 additions & 42 deletions server/src/main/java/com/soulfiremc/server/data/MineableType.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,56 +17,26 @@
*/
package com.soulfiremc.server.data;

import com.soulfiremc.server.protocol.bot.state.TagsState;
import java.util.Optional;
import java.util.Set;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public enum MineableType {
PICKAXE(
Set.of(
ItemType.WOODEN_PICKAXE,
ItemType.STONE_PICKAXE,
ItemType.IRON_PICKAXE,
ItemType.GOLDEN_PICKAXE,
ItemType.DIAMOND_PICKAXE,
ItemType.NETHERITE_PICKAXE),
BlockTags.MINEABLE_WITH_PICKAXE),
SHOVEL(
Set.of(
ItemType.WOODEN_SHOVEL,
ItemType.STONE_SHOVEL,
ItemType.IRON_SHOVEL,
ItemType.GOLDEN_SHOVEL,
ItemType.DIAMOND_SHOVEL,
ItemType.NETHERITE_SHOVEL),
BlockTags.MINEABLE_WITH_SHOVEL),
AXE(
Set.of(
ItemType.WOODEN_AXE,
ItemType.STONE_AXE,
ItemType.IRON_AXE,
ItemType.GOLDEN_AXE,
ItemType.DIAMOND_AXE,
ItemType.NETHERITE_AXE),
BlockTags.MINEABLE_WITH_AXE),
HOE(
Set.of(
ItemType.WOODEN_HOE,
ItemType.STONE_HOE,
ItemType.IRON_HOE,
ItemType.GOLDEN_HOE,
ItemType.DIAMOND_HOE,
ItemType.NETHERITE_HOE),
BlockTags.MINEABLE_WITH_HOE);
PICKAXE(ItemTags.PICKAXES, BlockTags.MINEABLE_WITH_PICKAXE),
SHOVEL(ItemTags.SHOVELS, BlockTags.MINEABLE_WITH_SHOVEL),
AXE(ItemTags.AXES, BlockTags.MINEABLE_WITH_AXE),
HOE(ItemTags.HOES, BlockTags.MINEABLE_WITH_HOE);

private final Set<ItemType> tools;
@Getter private final ResourceKey tagKey;
private final ResourceKey itemTagKey;
@Getter private final ResourceKey blockTagKey;

public static Optional<MineableType> getFromTool(ItemType itemType) {
for (var mineableType : MineableType.values()) {
if (mineableType.tools.contains(itemType)) {
public static MineableType[] VALUES = values();

public static Optional<MineableType> getFromTool(TagsState tagsState, ItemType itemType) {
for (var mineableType : VALUES) {
if (tagsState.isItemInTag(itemType, mineableType.itemTagKey)) {
return Optional.of(mineableType);
}
}
Expand Down
78 changes: 6 additions & 72 deletions server/src/main/java/com/soulfiremc/server/data/TierType.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,85 +17,19 @@
*/
package com.soulfiremc.server.data;

import java.util.OptionalInt;
import java.util.Set;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum TierType {
WOOD(
0,
2,
Set.of(
ItemType.WOODEN_PICKAXE,
ItemType.WOODEN_SHOVEL,
ItemType.WOODEN_AXE,
ItemType.WOODEN_HOE,
ItemType.WOODEN_SWORD)),
STONE(
1,
4,
Set.of(
ItemType.STONE_PICKAXE,
ItemType.STONE_SHOVEL,
ItemType.STONE_AXE,
ItemType.STONE_HOE,
ItemType.STONE_SWORD)),
IRON(
2,
6,
Set.of(
ItemType.IRON_PICKAXE,
ItemType.IRON_SHOVEL,
ItemType.IRON_AXE,
ItemType.IRON_HOE,
ItemType.IRON_SWORD)),
DIAMOND(
3,
8,
Set.of(
ItemType.DIAMOND_PICKAXE,
ItemType.DIAMOND_SHOVEL,
ItemType.DIAMOND_AXE,
ItemType.DIAMOND_HOE,
ItemType.DIAMOND_SWORD)),
GOLD(
0,
12,
Set.of(
ItemType.GOLDEN_PICKAXE,
ItemType.GOLDEN_SHOVEL,
ItemType.GOLDEN_AXE,
ItemType.GOLDEN_HOE,
ItemType.GOLDEN_SWORD)),
NETHERITE(
4,
9,
Set.of(
ItemType.NETHERITE_PICKAXE,
ItemType.NETHERITE_SHOVEL,
ItemType.NETHERITE_AXE,
ItemType.NETHERITE_HOE,
ItemType.NETHERITE_SWORD));

public static final TierType[] VALUES = values();
WOOD(0, 2),
STONE(1, 4),
IRON(2, 6),
DIAMOND(3, 8),
GOLD(0, 12),
NETHERITE(4, 9);

private final int level;
private final float miningSpeed;
private final Set<ItemType> tools;

public static OptionalInt getTier(ItemType itemType) {
for (var tierType : VALUES) {
// Loop instead of contains because we only need to do a == check
for (var tool : tierType.tools) {
if (tool == itemType) {
return OptionalInt.of(tierType.level);
}
}
}

return OptionalInt.empty();
}
}
51 changes: 19 additions & 32 deletions server/src/main/java/com/soulfiremc/server/data/ToolSpeedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,13 @@
package com.soulfiremc.server.data;

import com.soulfiremc.server.protocol.bot.state.TagsState;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ToolSpeedType {
private static final Set<ItemType> SWORDS =
Set.of(
ItemType.WOODEN_SWORD,
ItemType.STONE_SWORD,
ItemType.IRON_SWORD,
ItemType.GOLDEN_SWORD,
ItemType.DIAMOND_SWORD,
ItemType.NETHERITE_SWORD);

public static float getBlockToolSpeed(
TagsState tagsState, ItemType itemType, BlockType blockType) {
if (SWORDS.contains(itemType)) {
if (tagsState.isItemInTag(itemType, ItemTags.SWORDS)) {
if (blockType == BlockType.COBWEB) {
return 15;
} else if (tagsState.isBlockInTag(blockType, BlockTags.LEAVES)) {
Expand All @@ -51,22 +43,17 @@ public static float getBlockToolSpeed(
return 2;
}
} else {
return getEnumToolSpeed(tagsState, itemType, blockType);
return getTierToolSpeed(tagsState, itemType, blockType);
}
}

private static float getEnumToolSpeed(
private static float getTierToolSpeed(
TagsState tagsState, ItemType itemType, BlockType blockType) {
for (var toolSpeedType : TierType.values()) {
if (!toolSpeedType.tools().contains(itemType)) {
continue;
}

var tagName = MineableType.getFromTool(itemType).orElseThrow().tagKey();
if (tagsState.isBlockInTag(blockType, tagName)) {
return toolSpeedType.miningSpeed();
} else {
return 1;
var tierType = itemType.tierType();
if (tierType != null) {
var tagName = MineableType.getFromTool(tagsState, itemType);
if (tagName.isPresent() && tagsState.isBlockInTag(blockType, tagName.get().blockTagKey())) {
return tierType.miningSpeed();
}
}

Expand All @@ -76,29 +63,29 @@ private static float getEnumToolSpeed(

public static boolean isRightToolFor(
TagsState tagsState, ItemType itemType, BlockType blockType) {
if (SWORDS.contains(itemType)) {
if (tagsState.isItemInTag(itemType, ItemTags.SWORDS)) {
return blockType == BlockType.COBWEB;
} else if (itemType == ItemType.SHEARS) {
return blockType == BlockType.COBWEB
|| blockType == BlockType.REDSTONE_WIRE
|| blockType == BlockType.TRIPWIRE;
} else {
var tier = TierType.getTier(itemType);
if (tier.isEmpty()) {
var tier = itemType.tierType();
if (tier == null) {
return false;
}

var i = tier.getAsInt();
if (i < 3 && tagsState.isBlockInTag(blockType, BlockTags.NEEDS_DIAMOND_TOOL)) {
var level = tier.level();
if (level < 3 && tagsState.isBlockInTag(blockType, BlockTags.NEEDS_DIAMOND_TOOL)) {
return false;
} else if (i < 2 && tagsState.isBlockInTag(blockType, BlockTags.NEEDS_IRON_TOOL)) {
} else if (level < 2 && tagsState.isBlockInTag(blockType, BlockTags.NEEDS_IRON_TOOL)) {
return false;
} else if (i < 1 && tagsState.isBlockInTag(blockType, BlockTags.NEEDS_STONE_TOOL)) {
} else if (level < 1 && tagsState.isBlockInTag(blockType, BlockTags.NEEDS_STONE_TOOL)) {
return false;
}

return MineableType.getFromTool(itemType)
.filter(type -> tagsState.isBlockInTag(blockType, type.tagKey()))
return MineableType.getFromTool(tagsState, itemType)
.filter(type -> tagsState.isBlockInTag(blockType, type.blockTagKey()))
.isPresent();
}
}
Expand Down
Loading

0 comments on commit 97a9799

Please sign in to comment.