Compare commits

...

21 Commits

Author SHA1 Message Date
TheBrokenRail 69d8e0d218 1.0.29
RelicCraft/pipeline/head This commit looks good Details
2020-08-08 12:13:26 -04:00
TheBrokenRail d1f6af50af 1.0.28
RelicCraft/pipeline/head This commit looks good Details
Fix Server Crash
2020-08-05 14:44:53 -04:00
TheBrokenRail b58f4b0809 Reformat Code
RelicCraft/pipeline/head This commit looks good Details
2020-06-28 13:41:53 -04:00
TheBrokenRail 137502b603 Opt-In To ModUpdater
RelicCraft/pipeline/head This commit looks good Details
2020-06-28 12:40:56 -04:00
TheBrokenRail 462bd85adb Port To 1.16.1 2020-06-28 12:38:49 -04:00
TheBrokenRail 5167a1319d 1.0.27
RelicCraft/pipeline/head This commit looks good Details
Use DataTracker
2020-04-18 21:16:30 -04:00
TheBrokenRail bb35c94d12 1.0.26
RelicCraft/pipeline/head This commit looks good Details
Improve Teleportation Restrictor
2020-04-18 17:27:06 -04:00
TheBrokenRail 60db4606d2 1.0.25
RelicCraft/pipeline/head This commit looks good Details
Improve Teleportation Restrictor
2020-04-18 16:09:27 -04:00
TheBrokenRail 6f096b46cf Remove Useless Import
RelicCraft/pipeline/head This commit looks good Details
2020-04-18 15:15:22 -04:00
TheBrokenRail e77c6bff2e 1.0.24
RelicCraft/pipeline/head This commit looks good Details
Fix Teleportation Restrictor only affecting living entities
2020-04-16 12:17:12 -04:00
TheBrokenRail feac2483bb 1.0.23
RelicCraft/pipeline/head This commit looks good Details
Remove Max Count Limit From The Creative Relic Generator
2020-04-15 22:42:41 -04:00
TheBrokenRail a4d5069cdb 1.0.22
RelicCraft/pipeline/head This commit looks good Details
Standardize Mod Icon
2020-04-15 22:38:50 -04:00
TheBrokenRail c851d9b002 1.0.21
RelicCraft/pipeline/head This commit looks good Details
Tweak Statistics
2020-04-15 18:53:31 -04:00
TheBrokenRail 4763e9a76b 1.0.20
RelicCraft/pipeline/head This commit looks good Details
Tweak Item Handling in Creative Mode
2020-04-15 18:32:03 -04:00
TheBrokenRail bbf5965463 1.0.19
RelicCraft/pipeline/head This commit looks good Details
Rewrite Creative Relic Generator Tooltip
2020-04-15 18:21:27 -04:00
TheBrokenRail ca24f0a997 1.0.18
RelicCraft/pipeline/head This commit looks good Details
Give RelicCraft its own Item Group
Give Targeted Ender Pearls a Cooldown
Add Creative Relic Generator
2020-04-15 18:19:40 -04:00
TheBrokenRail 61732c4cd6 1.0.17
RelicCraft/pipeline/head This commit looks good Details
The Teleportation Restrictor now blocks Portal Teleportation
2020-04-15 16:35:03 -04:00
TheBrokenRail 56d88ebcb2 1.0.16
RelicCraft/pipeline/head This commit looks good Details
Register Loot Function
2020-04-11 13:39:12 -04:00
TheBrokenRail debafe02fb 1.0.15
RelicCraft/pipeline/head This commit looks good Details
Fix Ender Pearl Bug
2020-04-10 20:25:42 -04:00
TheBrokenRail 5d97fe0aa0 Update README
RelicCraft/pipeline/head This commit looks good Details
2020-04-09 23:07:21 -04:00
TheBrokenRail 378a0662c8 1.0.14
RelicCraft/pipeline/head This commit looks good Details
Fix Spawn Protection
2020-04-09 16:48:02 -04:00
53 changed files with 763 additions and 521 deletions

View File

@ -1,5 +1,55 @@
# Changelog
**1.10.29**
* Fix Log Warning
**1.0.28**
* Fix Server Crash
**1.0.27**
* Use DataTracker
**1.0.26**
* Improve Teleportation Restrictor
**1.0.25**
* Improve Teleportation Restrictor
**1.0.24**
* Fix Teleportation Restrictor only affecting living entities
**1.0.23**
* Remove Max Count Limit From The Creative Relic Generator
**1.0.22**
* Standardize Mod Icon
**1.0.21**
* Tweak Statistics
**1.0.20**
* Tweak Item Handling in Creative Mode
**1.0.19**
* Rewrite Creative Relic Generator Tooltip
**1.0.18**
* Give RelicCraft its own Item Group
* Give Targeted Ender Pearls a Cooldown
* Add Creative Relic Generator
**1.0.17**
* The Teleportation Restrictor now blocks Portal Teleportation
**1.0.16**
* Register Loot Function
**1.0.15**
* Fix Ender Pearl Bug
**1.0.14**
* Fix Spawn Protection
**1.0.13**
* Fix Bugs

View File

@ -15,8 +15,10 @@ This mod was created for [ModFest 1.15](https://modfest.github.io/1.15/)
* Teleportation Restrictors
* Fueled by a Dragon Egg
* 128x128x128 radius
* 4-Second Cooldown When Leaving Field
* Teleportation Beacons
* Fueled by a Dragon Egg
* Dragon Eggs are Now Renewable
## Changelog
[View Changelog](CHANGELOG.md)

View File

@ -1,7 +1,6 @@
plugins {
id 'fabric-loom' version '0.2.7-SNAPSHOT'
id 'com.matthewprenger.cursegradle' version '1.4.0'
id "com.github.johnrengelman.shadow" version "5.2.0"
}
compileJava {
@ -19,6 +18,16 @@ minecraft {
repositories {
jcenter()
maven {
name = 'Earthcomputer Mods'
url = 'https://dl.bintray.com/earthcomputer/mods'
}
}
configurations {
includeTransitive {
transitive = true
}
}
dependencies {
@ -27,37 +36,31 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
modImplementation "io.github.prospector:modmenu:${project.mod_menu_version}"
implementation "com.squareup.moshi:moshi:${project.moshi_version}"
shadow "com.squareup.moshi:moshi:${project.moshi_version}"
includeTransitive "com.squareup.moshi:moshi:${project.moshi_version}"
modImplementation "net.earthcomputer:libstructure:${project.libstructure_version}"
include "net.earthcomputer:libstructure:${project.libstructure_version}"
}
shadowJar {
configurations = [project.configurations.shadow]
classifier 'shadow-dev'
}
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
task relocateShadowJar(type: ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = "${project.group}.${project.archivesBaseName}.shadow"
}
tasks.shadowJar.dependsOn tasks.relocateShadowJar
remapJar {
dependsOn shadowJar
input.set shadowJar.archiveFile.get()
project.afterEvaluate {
configurations.includeTransitive.incoming.resolutionResult.allComponents {
if (it.id instanceof ModuleComponentIdentifier) {
def that = it
dependencies {
include group: that.id.getGroup(), name: that.id.getModule(), version: that.id.getVersion()
}
}
}
}
processResources {
inputs.property 'version', mod_version
inputs.property 'version', project.version
inputs.property 'name', rootProject.name
from(sourceSets.main.resources.srcDirs) {
include 'fabric.mod.json'
expand 'version': mod_version, 'name': rootProject.name
expand 'version': project.version, 'name': rootProject.name
}
from(sourceSets.main.resources.srcDirs) {

View File

@ -3,19 +3,19 @@ org.gradle.jvmargs = -Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version = 1.15.2
minecraft_version = 1.16.1
curseforge_id = 373074
simple_minecraft_version = 1.15.2
yarn_build = 15
fabric_loader_version = 0.7.10+build.191
simple_minecraft_version = 1.16.1
yarn_build = 16
fabric_loader_version = 0.8.8+build.202
# Mod Properties
mod_version = 1.0.13
mod_version = 1.0.29
maven_group = com.thebrokenrail
archives_base_name = reliccraft
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_api_version = 0.5.1+build.294-1.15
mod_menu_version = 1.10.2+build.32
fabric_api_version = 0.14.0+build.371-1.16
moshi_version = 1.9.2
libstructure_version = 1.3

View File

@ -12,30 +12,36 @@ import com.thebrokenrail.reliccraft.block.TeleportationBeaconBlock;
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
import com.thebrokenrail.reliccraft.entity.RelicEntity;
import com.thebrokenrail.reliccraft.item.DragonEggHolderBlockItem;
import com.thebrokenrail.reliccraft.item.GenerateRelicItem;
import com.thebrokenrail.reliccraft.item.RelicItem;
import com.thebrokenrail.reliccraft.item.TargetedEnderPearlItem;
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
import com.thebrokenrail.reliccraft.item.RelicItem;
import com.thebrokenrail.reliccraft.loot.RelicLootTableFunction;
import com.thebrokenrail.reliccraft.mixin.CriteriaRegistryHook;
import com.thebrokenrail.reliccraft.recipe.RevealRelicRecipe;
import com.thebrokenrail.reliccraft.recipe.TimeDilaterRecipe;
import com.thebrokenrail.reliccraft.structure.TimeTempleFeature;
import com.thebrokenrail.reliccraft.structure.TimeTempleGenerator;
import net.earthcomputer.libstructure.LibStructure;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.entity.FabricEntityTypeBuilder;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder;
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.fabricmc.fabric.api.tag.TagRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.EntityCategory;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.BinomialLootTableRange;
import net.minecraft.loot.LootTables;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.recipe.SpecialRecipeSerializer;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
@ -47,25 +53,19 @@ import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.chunk.FlatChunkGeneratorConfig;
import net.minecraft.world.gen.decorator.Decorator;
import net.minecraft.world.gen.decorator.DecoratorConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.chunk.StructureConfig;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import java.util.Locale;
public class RelicCraft implements ModInitializer {
public static final String NAMESPACE = "reliccraft";
public static Item ORB_ITEM;
public static Item STAFF_ITEM;
public static Item TIME_DILATER_ITEM;
public static Item TARGETED_ENDER_PEARL_ITEM;
public static Item GENERATE_RELIC_ITEM;
public static EntityType<RelicEntity> RELIC_ENTITY;
@ -119,31 +119,38 @@ public class RelicCraft implements ModInitializer {
world.playSound(null, pos, INTERACT_TELEPORT_RESTRICTOR_SOUND_EFFECT, SoundCategory.BLOCKS, 1.0f, 1.0f);
}
public static StructureFeature<DefaultFeatureConfig> TIME_TEMPLE_STRUCTURE_FEATURE = new TimeTempleFeature(DefaultFeatureConfig::deserialize);
public static StructureFeature<DefaultFeatureConfig> TIME_TEMPLE_STRUCTURE_FEATURE = new TimeTempleFeature(DefaultFeatureConfig.CODEC);
public static StructurePieceType TIME_TEMPLE_STRUCTURE_PIECE = TimeTempleGenerator.Piece::new;
public static final String TIME_TEMPLE_ID = "RelicCraft Time Temple";
public static ItemGroup ITEM_GROUP;
public final static Identifier TIME_TEMPLE_ID = new Identifier(NAMESPACE, "time_temple");
@Override
public void onInitialize() {
ITEM_GROUP = FabricItemGroupBuilder.build(new Identifier(NAMESPACE, "item_group"), () -> new ItemStack(TIME_DILATER_ITEM));
ORB_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "orb"), new RelicItem());
STAFF_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "staff"), new RelicItem());
TIME_DILATER_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "time_dilater"), new TimeDilaterItem());
TARGETED_ENDER_PEARL_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "targeted_ender_pearl"), new TargetedEnderPearlItem());
GENERATE_RELIC_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "generate_relic"), new GenerateRelicItem());
RELIC_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, (EntityType.EntityFactory<RelicEntity>) RelicEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build();
Identifier entityID = new Identifier(NAMESPACE, "relic_entity");
RELIC_ENTITY = Registry.register(Registry.ENTITY_TYPE, entityID, FabricEntityTypeBuilder.create(SpawnGroup.MISC, (EntityType.EntityFactory<RelicEntity>) RelicEntity::new).dimensions(new EntityDimensions(0.25f, 0.25f, true)).build());
LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> {
if (isSelectedLootTable(id)) {
FabricLootPoolBuilder poolBuilder = FabricLootPoolBuilder.builder()
.withRolls(new BinomialLootTableRange(2, 0.5f))
.withEntry(ItemEntry.builder(ORB_ITEM))
.withEntry(ItemEntry.builder(STAFF_ITEM))
.withFunction(new RelicLootTableFunction.Builder());
.rolls(new BinomialLootTableRange(2, 0.5f))
.withEntry(ItemEntry.builder(ORB_ITEM).build())
.withEntry(ItemEntry.builder(STAFF_ITEM).build())
.withFunction(new RelicLootTableFunction.Builder().build());
supplier.withPool(poolBuilder);
supplier.withPool(poolBuilder.build());
}
});
Registry.register(Registry.LOOT_FUNCTION_TYPE, new Identifier(NAMESPACE, "randomize_relic"), new LootFunctionType(new RelicLootTableFunction.Serializer()));
REVEAL_RELIC_RECIPE = Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(NAMESPACE, "reveal_relic"), new SpecialRecipeSerializer<>(RevealRelicRecipe::new));
TIME_DILATER_RECIPE = Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(NAMESPACE, "time_dilater"), new SpecialRecipeSerializer<>(TimeDilaterRecipe::new));
@ -166,28 +173,14 @@ public class RelicCraft implements ModInitializer {
//noinspection ResultOfMethodCallIgnored
TagRegistry.item(new Identifier(NAMESPACE, "relics"));
//noinspection ResultOfMethodCallIgnored
TagRegistry.item(new Identifier(NAMESPACE, "items"));
TagRegistry.item(new Identifier(NAMESPACE, "advancement_trigger_items"));
Registry.register(Registry.STRUCTURE_PIECE, new Identifier(NAMESPACE, "time_temple"), TIME_TEMPLE_STRUCTURE_PIECE);
Registry.register(Registry.FEATURE, new Identifier(NAMESPACE, "time_temple"), TIME_TEMPLE_STRUCTURE_FEATURE);
Registry.register(Registry.STRUCTURE_FEATURE, new Identifier(NAMESPACE, "time_temple"), TIME_TEMPLE_STRUCTURE_FEATURE);
Feature.STRUCTURES.put(TIME_TEMPLE_ID.toLowerCase(Locale.ROOT), TIME_TEMPLE_STRUCTURE_FEATURE);
ConfiguredFeature<?, ?> configuredFeature = getConfiguredFeature(TIME_TEMPLE_STRUCTURE_FEATURE);
for (Biome biome : Registry.BIOME) {
if (biome.getCategory() == Biome.Category.PLAINS) {
biome.addStructureFeature(TIME_TEMPLE_STRUCTURE_FEATURE.configure(FeatureConfig.DEFAULT));
}
}
FlatChunkGeneratorConfig.FEATURE_TO_GENERATION_STEP.put(configuredFeature, GenerationStep.Feature.SURFACE_STRUCTURES);
FlatChunkGeneratorConfig.FEATURE_TO_FEATURE_CONFIG.put(configuredFeature, FeatureConfig.DEFAULT);
FlatChunkGeneratorConfig.STRUCTURE_TO_FEATURES.put(NAMESPACE + "_time_temple", new ConfiguredFeature[]{configuredFeature});
}
public static ConfiguredFeature<?, ?> getConfiguredFeature(StructureFeature<DefaultFeatureConfig> feature) {
return feature.configure(FeatureConfig.DEFAULT).createDecoratedFeature(Decorator.NOPE.configure(DecoratorConfig.DEFAULT));
LibStructure.registerStructure(TIME_TEMPLE_ID, TIME_TEMPLE_STRUCTURE_FEATURE, GenerationStep.Feature.SURFACE_STRUCTURES, new StructureConfig(32, 8, 14357618), TIME_TEMPLE_STRUCTURE_FEATURE.configure(FeatureConfig.DEFAULT));
}
}

View File

@ -1,14 +1,15 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class ActivateTeleportationBeaconCriterion extends AbstractCriterion<ActivateTeleportationBeaconCriterion.Conditions> {
public class ActivateTeleportationBeaconCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "activate_teleportation_beacon");
public ActivateTeleportationBeaconCriterion() {
@ -20,17 +21,12 @@ public class ActivateTeleportationBeaconCriterion extends AbstractCriterion<Acti
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -1,36 +1,32 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class ActivateTeleportationRestrictorCriterion extends AbstractCriterion<ActivateTeleportationRestrictorCriterion.Conditions> {
public class ActivateTeleportationRestrictorCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "activate_teleportation_restrictor");
public ActivateTeleportationRestrictorCriterion() {
}
@Override
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
@Override
public Identifier getId() {
return ID;
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -1,14 +1,15 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class DilateTimeCriterion extends AbstractCriterion<DilateTimeCriterion.Conditions> {
public class DilateTimeCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "dilate_time");
public DilateTimeCriterion() {
@ -20,17 +21,12 @@ public class DilateTimeCriterion extends AbstractCriterion<DilateTimeCriterion.C
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -1,14 +1,15 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class DuplicateTimeDilaterCriterion extends AbstractCriterion<DuplicateTimeDilaterCriterion.Conditions> {
public class DuplicateTimeDilaterCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "duplicate_time_dilater");
public DuplicateTimeDilaterCriterion() {
@ -20,17 +21,12 @@ public class DuplicateTimeDilaterCriterion extends AbstractCriterion<DuplicateTi
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -1,14 +1,15 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class RevealRelicCriterion extends AbstractCriterion<RevealRelicCriterion.Conditions> {
public class RevealRelicCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "reveal_relic");
public RevealRelicCriterion() {
@ -20,17 +21,12 @@ public class RevealRelicCriterion extends AbstractCriterion<RevealRelicCriterion
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -1,14 +1,15 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class UseTargetedEnderPearlCriterion extends AbstractCriterion<UseTargetedEnderPearlCriterion.Conditions> {
public class UseTargetedEnderPearlCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "use_targeted_ender_pearl");
public UseTargetedEnderPearlCriterion() {
@ -20,17 +21,12 @@ public class UseTargetedEnderPearlCriterion extends AbstractCriterion<UseTargete
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -1,14 +1,15 @@
package com.thebrokenrail.reliccraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class UseTeleportationBeaconCriterion extends AbstractCriterion<UseTeleportationBeaconCriterion.Conditions> {
public class UseTeleportationBeaconCriterion extends AbstractCriterion<AbstractCriterionConditions> {
private static final Identifier ID = new Identifier(RelicCraft.NAMESPACE, "use_teleportation_beacon");
public UseTeleportationBeaconCriterion() {
@ -20,17 +21,12 @@ public class UseTeleportationBeaconCriterion extends AbstractCriterion<UseTelepo
}
@Override
public Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new Conditions();
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new AbstractCriterionConditions(ID, playerPredicate) {
};
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), conditions -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
}
test(player, conditions -> true);
}
}

View File

@ -6,11 +6,11 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.container.Container;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.state.StateManager;
@ -30,46 +30,41 @@ public abstract class AbstractDragonEggHolderBlock extends Block implements Bloc
public static final BooleanProperty ACTIVE = BooleanProperty.of("active");
public AbstractDragonEggHolderBlock(Settings settings) {
super(settings);
super(settings.lightLevel(state -> state.get(ACTIVE) ? 7 : 0));
setDefaultState(getStateManager().getDefaultState().with(ACTIVE, false));
}
@Override
public int getLuminance(BlockState state) {
return state.get(ACTIVE) ? 7 : 0;
}
@Override
public BlockEntity createBlockEntity(BlockView view) {
return new DragonEggHolderBlockEntity();
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity user, Hand hand, BlockHitResult hit) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof Inventory) {
Inventory inventory = (Inventory) blockEntity;
ItemStack stack = player.getStackInHand(hand);
ItemStack stack = user.getStackInHand(hand);
if (!stack.isEmpty()) {
if (inventory.isValidInvStack(0, stack) && inventory.getInvStack(0).isEmpty()) {
inventory.setInvStack(0, stack.split(1));
if (!world.isClient()) {
grantAdvancement(player);
}
if (inventory.isValid(0, stack) && inventory.getStack(0).isEmpty()) {
inventory.setStack(0, stack.split(1));
if (!world.isClient()) {
grantAdvancement(user);
}
return ActionResult.SUCCESS;
} else if (stack.isEmpty()) {
if (!inventory.getStack(0).isEmpty()) {
user.inventory.offerOrDrop(world, inventory.getStack(0));
inventory.removeStack(0);
return ActionResult.SUCCESS;
} else {
return ActionResult.PASS;
}
} else {
if (!inventory.getInvStack(0).isEmpty()) {
player.inventory.offerOrDrop(world, inventory.getInvStack(0));
inventory.removeInvStack(0);
return ActionResult.SUCCESS;
} else {
return ActionResult.PASS;
}
return ActionResult.PASS;
}
} else {
return ActionResult.FAIL;
@ -98,14 +93,14 @@ public abstract class AbstractDragonEggHolderBlock extends Block implements Bloc
}
@Override
public void onBlockRemoved(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (state.getBlock() != newState.getBlock()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof Inventory) {
ItemScatterer.spawn(world, pos, (Inventory) blockEntity);
}
super.onBlockRemoved(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
}
@ -121,10 +116,10 @@ public abstract class AbstractDragonEggHolderBlock extends Block implements Bloc
@Override
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
return Container.calculateComparatorOutput(world.getBlockEntity(pos));
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
}
public abstract void tick(World world, BlockPos pos, Inventory inventory);
public abstract void tick(World world, BlockPos pos);
public abstract void grantAdvancement(PlayerEntity player);
}

View File

@ -10,8 +10,10 @@ import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.DefaultedList;
import net.minecraft.util.Tickable;
import net.minecraft.util.collection.DefaultedList;
import java.util.Objects;
public class DragonEggHolderBlockEntity extends BlockEntity implements Inventory, Tickable {
public DragonEggHolderBlockEntity() {
@ -19,16 +21,16 @@ public class DragonEggHolderBlockEntity extends BlockEntity implements Inventory
}
@Override
public void fromTag(CompoundTag tag) {
super.fromTag(tag);
DefaultedList<ItemStack> list = DefaultedList.ofSize(getInvSize(), ItemStack.EMPTY);
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
DefaultedList<ItemStack> list = DefaultedList.ofSize(size(), ItemStack.EMPTY);
Inventories.fromTag(tag, list);
stack = list.get(0);
}
@Override
public CompoundTag toTag(CompoundTag tag) {
DefaultedList<ItemStack> list = DefaultedList.ofSize(getInvSize(), ItemStack.EMPTY);
DefaultedList<ItemStack> list = DefaultedList.ofSize(size(), ItemStack.EMPTY);
list.set(0, stack);
Inventories.toTag(tag, list);
return super.toTag(tag);
@ -37,56 +39,56 @@ public class DragonEggHolderBlockEntity extends BlockEntity implements Inventory
private ItemStack stack = ItemStack.EMPTY;
@Override
public int getInvSize() {
public int size() {
return 1;
}
@Override
public int getInvMaxStackAmount() {
public int getMaxCountPerStack() {
return 1;
}
@Override
public boolean isInvEmpty() {
public boolean isEmpty() {
return stack.isEmpty();
}
@Override
public ItemStack getInvStack(int slot) {
public ItemStack getStack(int slot) {
return stack;
}
@Override
public ItemStack takeInvStack(int slot, int amount) {
ItemStack newStack = getInvStack(0).split(amount);
public ItemStack removeStack(int slot, int amount) {
ItemStack newStack = getStack(0).split(amount);
markDirty();
return newStack;
}
@Override
public ItemStack removeInvStack(int slot) {
ItemStack newStack = getInvStack(0).copy();
setInvStack(0, ItemStack.EMPTY);
public ItemStack removeStack(int slot) {
ItemStack newStack = getStack(0).copy();
setStack(0, ItemStack.EMPTY);
return newStack;
}
@Override
public void setInvStack(int slot, ItemStack stack) {
public void setStack(int slot, ItemStack stack) {
this.stack = stack;
if (stack.getCount() > getInvMaxStackAmount()) {
stack.setCount(getInvMaxStackAmount());
if (stack.getCount() > getMaxCountPerStack()) {
stack.setCount(getMaxCountPerStack());
}
markDirty();
}
@Override
public boolean canPlayerUseInv(PlayerEntity player) {
public boolean canPlayerUse(PlayerEntity player) {
return true;
}
@Override
public void clear() {
setInvStack(0, ItemStack.EMPTY);
setStack(0, ItemStack.EMPTY);
}
@Override
@ -94,28 +96,30 @@ public class DragonEggHolderBlockEntity extends BlockEntity implements Inventory
if (hasWorld()) {
assert getWorld() != null;
Block block = getWorld().getBlockState(getPos()).getBlock();
if (block instanceof AbstractDragonEggHolderBlock) {
((AbstractDragonEggHolderBlock) block).tick(getWorld(), getPos(), this);
if (block instanceof AbstractDragonEggHolderBlock && !getWorld().isClient()) {
((AbstractDragonEggHolderBlock) block).tick(getWorld(), getPos());
}
}
}
@Override
public boolean isValidInvStack(int slot, ItemStack stack) {
public boolean isValid(int slot, ItemStack stack) {
return stack.getItem() == Items.DRAGON_EGG;
}
@Override
public void markDirty() {
super.markDirty();
updateBlockState();
if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) {
updateBlockState();
}
}
private void updateBlockState() {
if (hasWorld()) {
assert getWorld() != null;
BlockState state = getWorld().getBlockState(pos);
boolean active = !getInvStack(0).isEmpty();
boolean active = !getStack(0).isEmpty();
if (state.get(TeleportationRestrictorBlock.ACTIVE) != active) {
getWorld().setBlockState(getPos(), state.with(TeleportationRestrictorBlock.ACTIVE, active));
RelicCraft.playInteractTeleportRestrictorSound(getWorld(), getPos());

View File

@ -5,7 +5,6 @@ import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.math.BlockPos;
@ -17,7 +16,7 @@ public class TeleportationBeaconBlock extends AbstractDragonEggHolderBlock {
}
@Override
public void tick(World world, BlockPos pos, Inventory inventory) {
public void tick(World world, BlockPos pos) {
}
@Override

View File

@ -2,11 +2,11 @@ package com.thebrokenrail.reliccraft.block;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
@ -26,11 +26,12 @@ public class TeleportationRestrictorBlock extends AbstractDragonEggHolderBlock {
}
@Override
public void tick(World world, BlockPos pos, Inventory inventory) {
int radius = !inventory.getInvStack(0).isEmpty() ? 128 : 0;
public void tick(World world, BlockPos pos) {
BlockState state = world.getBlockState(pos);
int radius = state.get(ACTIVE) ? 128 : 0;
Box box = new Box(pos).expand(radius);
List<LivingEntity> list = world.getNonSpectatingEntities(LivingEntity.class, box);
for (LivingEntity entity : list) {
List<Entity> list = world.getEntities(Entity.class, box, null);
for (Entity entity : list) {
((TeleportingEntity) entity).resetTeleportCooldown();
}
}

View File

@ -2,6 +2,7 @@ package com.thebrokenrail.reliccraft.client;
import com.thebrokenrail.reliccraft.RelicCraft;
import com.thebrokenrail.reliccraft.client.entity.RelicEntityRenderer;
import com.thebrokenrail.reliccraft.item.DragonEggHolderBlockItem;
import com.thebrokenrail.reliccraft.item.RelicItem;
import com.thebrokenrail.reliccraft.packet.UpdateTimeDilationS2CPacket;
import net.fabricmc.api.ClientModInitializer;
@ -25,13 +26,38 @@ public class RelicCraftClient implements ClientModInitializer {
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch ((int) (i % 6)) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
default: throw new UnsupportedOperationException();
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
default:
throw new UnsupportedOperationException();
}
return rgbToDecimal(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
}
@ -50,6 +76,8 @@ public class RelicCraftClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
DragonEggHolderBlockItem.initClient();
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex > 0 ? -1 : getStackColor(stack), RelicCraft.ORB_ITEM);
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex > 0 ? -1 : getStackColor(stack), RelicCraft.STAFF_ITEM);

View File

@ -1,19 +1,18 @@
package com.thebrokenrail.reliccraft.data;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface Action {
void execute(World world, LivingEntity attacker, Entity target);
void execute(World world, Entity attacker, Entity target);
void execute(World world, LivingEntity attacker, BlockPos pos);
void execute(World world, Entity attacker, BlockPos pos);
int getCost();
default PlayerEntity convertToPlayer(LivingEntity entity) {
default PlayerEntity convertToPlayer(Entity entity) {
if (entity instanceof PlayerEntity) {
return (PlayerEntity) entity;
} else {

View File

@ -6,16 +6,19 @@ import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnType;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.mob.ZombieEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.thrown.PotionEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.PotionUtil;
import net.minecraft.potion.Potions;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import java.util.ArrayList;
import java.util.HashMap;
@ -70,29 +73,34 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
if (target instanceof LivingEntity) {
((LivingEntity) target).setHealth(1f);
}
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
public void execute(World world, Entity attacker, BlockPos pos) {
PotionEntity entity = new PotionEntity(world, pos.getX(), pos.getY(), pos.getZ());
entity.setItem(PotionUtil.setPotion(new ItemStack(Items.LINGERING_POTION), Potions.STRONG_HARMING));
world.spawnEntity(entity);
}
}
public static class SwapBlockAction implements Action {
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
execute(world, attacker, target.getBlockPos().down());
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
BlockState state1 = world.getBlockState(attacker.getBlockPos().down());
BlockState state2 = world.getBlockState(pos);
world.setBlockState(attacker.getBlockPos().down(), state2);
world.setBlockState(pos, state1);
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos) && world.canPlayerModifyAt((PlayerEntity) attacker, attacker.getBlockPos().down())) {
BlockState state1 = world.getBlockState(attacker.getBlockPos().down());
BlockState state2 = world.getBlockState(pos);
world.setBlockState(attacker.getBlockPos().down(), state2);
world.setBlockState(pos, state1);
}
}
@Override
@ -108,15 +116,19 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
target.remove();
target.kill();
world.setBlockState(target.getBlockPos(), Blocks.DIRT.getDefaultState());
public void execute(World world, Entity attacker, Entity target) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, target.getBlockPos())) {
target.remove();
target.kill();
world.setBlockState(target.getBlockPos(), Blocks.DIRT.getDefaultState());
}
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
world.setBlockState(pos, Blocks.DIRT.getDefaultState());
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) {
world.setBlockState(pos, Blocks.DIRT.getDefaultState());
}
}
}
@ -127,17 +139,19 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
BlockPos pos = target.getBlockPos();
BlockState state = world.getBlockState(pos);
world.setBlockState(pos, Blocks.NETHER_PORTAL.getDefaultState());
target.changeDimension(world.dimension.getType() == DimensionType.THE_NETHER ? DimensionType.OVERWORLD : DimensionType.THE_NETHER);
target.changeDimension(((ServerWorld) world).getServer().getWorld(world.getRegistryKey() == World.NETHER ? World.OVERWORLD : World.NETHER));
world.setBlockState(pos, state);
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
world.setBlockState(pos, Blocks.LAVA.getDefaultState());
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) {
world.setBlockState(pos, Blocks.LAVA.getDefaultState());
}
}
}
@ -148,13 +162,15 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
target.changeDimension(world.dimension.getType() == DimensionType.THE_END ? DimensionType.OVERWORLD : DimensionType.THE_END);
public void execute(World world, Entity attacker, Entity target) {
target.changeDimension(((ServerWorld) world).getServer().getWorld(world.getRegistryKey() == World.END ? World.OVERWORLD : World.END));
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
world.setBlockState(pos, Blocks.END_STONE.getDefaultState());
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) {
world.setBlockState(pos, Blocks.END_STONE.getDefaultState());
}
}
}
@ -198,21 +214,21 @@ public class Actions {
public abstract Block getConvertedBlock();
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
if (target instanceof PlayerEntity) {
PlayerEntity player = (PlayerEntity) target;
for (int i = 0; i < player.inventory.getInvSize(); i++) {
ItemStack stack = player.inventory.getInvStack(i);
for (int i = 0; i < player.inventory.size(); i++) {
ItemStack stack = player.inventory.getStack(i);
if (stack.getItem() == getTargetItem()) {
player.inventory.setInvStack(i, new ItemStack(getConvertedItem(), stack.getCount()));
player.inventory.setStack(i, new ItemStack(getConvertedItem(), stack.getCount()));
}
}
}
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
if (world.getBlockState(pos).getBlock() == getTargetBlock()) {
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos) && world.getBlockState(pos).getBlock() == getTargetBlock()) {
world.setBlockState(pos, getConvertedBlock().getDefaultState());
}
}
@ -248,19 +264,23 @@ public class Actions {
public static class BedrockAction implements Action {
@Override
public int getCost() {
return 90;
return 95;
}
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
target.remove();
target.kill();
world.setBlockState(target.getBlockPos(), Blocks.BEDROCK.getDefaultState());
public void execute(World world, Entity attacker, Entity target) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, attacker.getBlockPos())) {
target.remove();
target.kill();
world.setBlockState(target.getBlockPos(), Blocks.BEDROCK.getDefaultState());
}
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
world.setBlockState(pos, Blocks.BEDROCK.getDefaultState());
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) {
world.setBlockState(pos, Blocks.BEDROCK.getDefaultState());
}
}
}
@ -271,20 +291,23 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
if (target instanceof LivingEntity) {
((LivingEntity) target).heal(Float.MAX_VALUE);
}
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
public void execute(World world, Entity attacker, BlockPos pos) {
PotionEntity entity = new PotionEntity(world, pos.getX(), pos.getY(), pos.getZ());
entity.setItem(PotionUtil.setPotion(new ItemStack(Items.LINGERING_POTION), Potions.STRONG_HEALING));
world.spawnEntity(entity);
}
}
public static class ZombifyAction implements Action {
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
ZombieEntity zombie = new ZombieEntity(world);
zombie.updatePosition(target.getX(), target.getY(), target.getZ());
world.spawnEntity(zombie);
@ -293,7 +316,7 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
public void execute(World world, Entity attacker, BlockPos pos) {
ZombieEntity zombie = new ZombieEntity(world);
zombie.updatePosition(attacker.getX(), attacker.getY(), attacker.getZ());
world.spawnEntity(zombie);
@ -309,7 +332,7 @@ public class Actions {
public static class RandomAction implements Action {
@Override
public void execute(World world, LivingEntity attacker, Entity target) {
public void execute(World world, Entity attacker, Entity target) {
if (!target.removed) {
target.remove();
target.kill();
@ -317,7 +340,7 @@ public class Actions {
int entityID = new Random().nextInt(Registry.ENTITY_TYPE.getIds().size());
EntityType<?> entityType = Registry.ENTITY_TYPE.get(entityID);
if (entityType.isSummonable()) {
Entity entity = entityType.spawn(world, null, null, convertToPlayer(attacker), target.getBlockPos(), SpawnType.CONVERSION, false, false);
Entity entity = entityType.spawn(world, null, null, convertToPlayer(attacker), target.getBlockPos(), SpawnReason.CONVERSION, false, false);
if (entity != null) {
entity.updatePosition(target.getX(), target.getY(), target.getZ());
} else {
@ -329,10 +352,12 @@ public class Actions {
}
@Override
public void execute(World world, LivingEntity attacker, BlockPos pos) {
int blockID = new Random().nextInt(Registry.BLOCK.getIds().size());
Block block = Registry.BLOCK.get(blockID);
world.setBlockState(pos, block.getDefaultState());
public void execute(World world, Entity attacker, BlockPos pos) {
if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) {
int blockID = new Random().nextInt(Registry.BLOCK.getIds().size());
Block block = Registry.BLOCK.get(blockID);
world.setBlockState(pos, block.getDefaultState());
}
}
@Override

View File

@ -38,6 +38,7 @@ public class RelicData {
TARGET,
SELF
}
public String[] actions = new String[0];
public Mode mode = Mode.SELF;
}

View File

@ -7,7 +7,7 @@ import com.thebrokenrail.reliccraft.item.RelicItem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.thrown.ThrownItemEntity;
import net.minecraft.entity.projectile.thrown.ThrownItemEntity;
import net.minecraft.item.Item;
import net.minecraft.network.Packet;
import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket;

View File

@ -1,29 +1,43 @@
package com.thebrokenrail.reliccraft.item;
import com.thebrokenrail.reliccraft.RelicCraft;
import com.thebrokenrail.reliccraft.mixin.ModelPredicateProviderRegistryHook;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.inventory.Inventories;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.DefaultedList;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rarity;
import net.minecraft.util.collection.DefaultedList;
import java.util.ArrayList;
import java.util.List;
public class DragonEggHolderBlockItem extends BlockItem {
private static final List<DragonEggHolderBlockItem> list = new ArrayList<>();
public DragonEggHolderBlockItem(Block block) {
super(block, new Settings().rarity(Rarity.UNCOMMON).group(ItemGroup.MISC));
addPropertyGetter(new Identifier(RelicCraft.NAMESPACE, "active"), (stack, world, entity) -> {
CompoundTag tag = stack.getSubTag("BlockEntityTag");
if (tag != null) {
DefaultedList<ItemStack> list = DefaultedList.ofSize(1, ItemStack.EMPTY);
Inventories.fromTag(tag, list);
if (!list.get(0).isEmpty()) {
return 1;
super(block, new Settings().rarity(Rarity.UNCOMMON).group(RelicCraft.ITEM_GROUP));
list.add(this);
}
@Environment(EnvType.CLIENT)
public static void initClient() {
for (DragonEggHolderBlockItem item : list) {
ModelPredicateProviderRegistryHook.callRegister(item, new Identifier(RelicCraft.NAMESPACE, "active"), (stack, world, entity) -> {
CompoundTag tag = stack.getSubTag("BlockEntityTag");
if (tag != null) {
DefaultedList<ItemStack> list = DefaultedList.ofSize(1, ItemStack.EMPTY);
Inventories.fromTag(tag, list);
if (!list.get(0).isEmpty()) {
return 1;
}
}
}
return 0;
});
return 0;
});
}
}
}

View File

@ -0,0 +1,72 @@
package com.thebrokenrail.reliccraft.item;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import com.thebrokenrail.reliccraft.RelicCraft;
import com.thebrokenrail.reliccraft.data.RelicData;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.stat.Stats;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.Rarity;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import java.util.List;
public class GenerateRelicItem extends Item {
public GenerateRelicItem() {
super(new Settings().group(RelicCraft.ITEM_GROUP).rarity(Rarity.UNCOMMON));
}
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
ItemStack stack = user.getStackInHand(hand);
if (!world.isClient()) {
user.incrementStat(Stats.USED.getOrCreateStat(this));
RelicCraft.playRelicSound(user);
ItemStack newStack;
if (RANDOM.nextBoolean()) {
newStack = new ItemStack(RelicCraft.ORB_ITEM);
} else {
newStack = new ItemStack(RelicCraft.STAFF_ITEM);
}
CompoundTag tag = new CompoundTag();
Moshi moshi = new Moshi.Builder().build();
JsonAdapter<RelicData> jsonAdapter = moshi.adapter(RelicData.class);
tag.putString("RelicData", jsonAdapter.toJson(RelicData.generate(RANDOM)));
newStack.setTag(tag);
if (!user.isCreative()) {
stack.decrement(1);
}
if (!user.inventory.insertStack(newStack.copy())) {
user.dropItem(newStack, false);
}
}
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
}
@Override
public void appendTooltip(ItemStack stack, World world, List<Text> tooltip, TooltipContext context) {
tooltip.add(new TranslatableText("item." + RelicCraft.NAMESPACE + ".generate_relic.tooltip").formatted(Formatting.GRAY));
}
@Override
public boolean hasGlint(ItemStack stack) {
return true;
}
}

View File

@ -15,6 +15,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
@ -27,6 +28,7 @@ import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.Rarity;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -34,7 +36,11 @@ import java.util.List;
public class RelicItem extends Item {
public RelicItem() {
super(new Settings().rarity(Rarity.UNCOMMON).maxDamage(1));
super(new Settings().group(RelicCraft.ITEM_GROUP).rarity(Rarity.UNCOMMON).maxDamage(1));
}
@Override
public void appendStacks(ItemGroup group, DefaultedList<ItemStack> stacks) {
}
@Override
@ -64,9 +70,9 @@ public class RelicItem extends Item {
}
@Override
public boolean hasEnchantmentGlint(ItemStack stack) {
public boolean hasGlint(ItemStack stack) {
RelicData data = getData(stack);
return super.hasEnchantmentGlint(stack) || data.enchantmentGlint;
return super.hasGlint(stack) || data.enchantmentGlint;
}
@Override
@ -128,7 +134,7 @@ public class RelicItem extends Item {
}
@Override
public boolean useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) {
public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) {
RelicData data = getData(stack);
if (data.use.mode == RelicData.UseData.Mode.TARGET) {
if (!user.getEntityWorld().isClient()) {
@ -138,9 +144,9 @@ public class RelicItem extends Item {
}
damage(stack, user, hand);
return true;
return ActionResult.SUCCESS;
} else {
return false;
return ActionResult.PASS;
}
}

View File

@ -6,16 +6,18 @@ import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.datafixer.NbtOps;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.stat.Stats;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
@ -27,18 +29,19 @@ import net.minecraft.util.Rarity;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import java.util.List;
import java.util.UUID;
public class TargetedEnderPearlItem extends Item {
public TargetedEnderPearlItem() {
super(new Settings().rarity(Rarity.UNCOMMON).group(ItemGroup.MISC).maxCount(16));
super(new Settings().rarity(Rarity.UNCOMMON).group(RelicCraft.ITEM_GROUP).maxCount(16));
}
@Override
public boolean hasEnchantmentGlint(ItemStack stack) {
public boolean hasGlint(ItemStack stack) {
return true;
}
@ -46,7 +49,11 @@ public class TargetedEnderPearlItem extends Item {
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
ItemStack stack = user.getStackInHand(hand);
user.getItemCooldownManager().set(this, 20);
if (!world.isClient()) {
user.incrementStat(Stats.USED.getOrCreateStat(this));
CompoundTag tag = stack.getTag();
if (tag == null) {
return new TypedActionResult<>(ActionResult.FAIL, stack);
@ -54,16 +61,16 @@ public class TargetedEnderPearlItem extends Item {
BlockPos target = new BlockPos(tag.getInt("TargetX"), tag.getInt("TargetY"), tag.getInt("TargetZ"));
Vec3d teleportTarget = new Vec3d(target.getX() + 0.5d, target.getY() + 1.0d, target.getZ() + 0.5d);
DimensionType dimension = DimensionType.byId(new Identifier(tag.getString("TargetDimension")));
RegistryKey<World> dimension = World.CODEC.parse(NbtOps.INSTANCE, tag.get("TargetDimension")).result().orElse(World.OVERWORLD);
if (user.dimension != dimension || dimension == null) {
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_in_different_dimension"));
if (user.getEntityWorld().getRegistryKey() != dimension || dimension == null) {
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_in_different_dimension"), false);
return new TypedActionResult<>(ActionResult.FAIL, stack);
} else if (((TeleportationRestrictorBlock.TeleportingEntity) user).cannotTeleport()) {
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_restricted"));
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_restricted"), false);
return new TypedActionResult<>(ActionResult.FAIL, stack);
} else if (world.getBlockState(target).getBlock() != RelicCraft.TELEPORTATION_BEACON_BLOCK || !world.getBlockState(target).get(AbstractDragonEggHolderBlock.ACTIVE)) {
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".missing_teleportation_beacon"));
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".missing_teleportation_beacon"), false);
return new TypedActionResult<>(ActionResult.FAIL, stack);
} else {
Vec3d oldPos = user.getPos();
@ -81,7 +88,7 @@ public class TargetedEnderPearlItem extends Item {
stack.decrement(1);
}
} else {
user.sendMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_obstructed"));
user.sendSystemMessage(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".teleportation_beacon_obstructed"), UUID.randomUUID());
return new TypedActionResult<>(ActionResult.FAIL, stack);
}
}
@ -106,7 +113,7 @@ public class TargetedEnderPearlItem extends Item {
Identifier id = new Identifier(tag.getString("TargetDimension"));
String key = "text." + RelicCraft.NAMESPACE + ".dimension." + id.getNamespace() + '.' + id.getPath();
Text dimensionText;
MutableText dimensionText;
if (Language.getInstance().hasTranslation(key)) {
dimensionText = new TranslatableText(key);
} else {

View File

@ -7,18 +7,23 @@ import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.MessageType;
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.stat.Stats;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rarity;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.Util;
import net.minecraft.world.PersistentState;
import net.minecraft.world.World;
import java.util.List;
@ -30,18 +35,52 @@ public class TimeDilaterItem extends Item {
VERY_FAST
}
public static final String TIME_SPEED_KEY = new Identifier(RelicCraft.NAMESPACE, "time_speed").toString();
public static class TimeSpeedState extends PersistentState {
private TimeSpeed timeSpeed = TimeSpeed.NORMAL;
public TimeSpeedState() {
super(TIME_SPEED_KEY);
}
public void setTimeSpeed(TimeSpeed timeSpeed) {
this.timeSpeed = timeSpeed;
markDirty();
}
public TimeSpeed getTimeSpeed() {
return timeSpeed;
}
@Override
public void fromTag(CompoundTag tag) {
timeSpeed = TimeSpeed.valueOf(tag.getString("TimeSpeed"));
}
@Override
public CompoundTag toTag(CompoundTag tag) {
tag.putString("TimeSpeed", timeSpeed.name());
return tag;
}
}
public interface DilatedWorld {
void setTimeSpeed(TimeSpeed speed);
TimeSpeed getTimeSpeed();
}
public TimeDilaterItem() {
super(new Settings().group(ItemGroup.MISC).maxDamage(9).rarity(Rarity.UNCOMMON));
super(new Settings().group(RelicCraft.ITEM_GROUP).maxDamage(9).rarity(Rarity.UNCOMMON));
}
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
ItemStack stack = user.getStackInHand(hand);
user.incrementStat(Stats.USED.getOrCreateStat(this));
if (!world.isClient()) {
DilatedWorld dilatedWorld = (DilatedWorld) world;
switch (dilatedWorld.getTimeSpeed()) {
@ -59,12 +98,13 @@ public class TimeDilaterItem extends Item {
}
}
assert world.getServer() != null;
world.getServer().getPlayerManager().sendToAll(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change", user.getDisplayName(), new LiteralText("[").append(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change." + dilatedWorld.getTimeSpeed().name().toLowerCase())).append("]").formatted(Formatting.YELLOW)));
world.getServer().getPlayerManager().sendToAll(new GameMessageS2CPacket(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change", user.getDisplayName(), new LiteralText("[").append(new TranslatableText("chat." + RelicCraft.NAMESPACE + ".announce_time_speed_change." + dilatedWorld.getTimeSpeed().name().toLowerCase())).append("]").formatted(Formatting.YELLOW)), MessageType.CHAT, Util.NIL_UUID));
RelicCraft.DILATE_TIME_CRITERION.trigger((ServerPlayerEntity) user);
}
RelicCraft.playRelicSound(user);
stack.damage(1, user, e -> e.sendToolBreakStatus(hand));
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
}

View File

@ -1,17 +1,23 @@
package com.thebrokenrail.reliccraft.loot;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import com.thebrokenrail.reliccraft.RelicCraft;
import com.thebrokenrail.reliccraft.data.RelicData;
import net.minecraft.item.ItemStack;
import net.minecraft.loot.condition.LootCondition;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.function.ConditionalLootFunction;
import net.minecraft.loot.function.LootFunction;
import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class RelicLootTableFunction extends ConditionalLootFunction {
private RelicLootTableFunction(LootCondition[] conditions) {
protected RelicLootTableFunction(LootCondition[] conditions) {
super(conditions);
}
@ -28,6 +34,22 @@ public class RelicLootTableFunction extends ConditionalLootFunction {
return stack;
}
@Override
public LootFunctionType getType() {
return Registry.LOOT_FUNCTION_TYPE.get(new Identifier(RelicCraft.NAMESPACE, "randomize_relic"));
}
public static class Serializer extends ConditionalLootFunction.Serializer<RelicLootTableFunction> {
public Serializer() {
super();
}
@Override
public RelicLootTableFunction fromJson(JsonObject json, JsonDeserializationContext context, LootCondition[] conditions) {
return (RelicLootTableFunction) new Builder().build();
}
}
public static class Builder extends ConditionalLootFunction.Builder<RelicLootTableFunction.Builder> {
@Override
protected RelicLootTableFunction.Builder getThisBuilder() {
@ -38,5 +60,4 @@ public class RelicLootTableFunction extends ConditionalLootFunction {
return new RelicLootTableFunction(getConditions());
}
}
}
}

View File

@ -1,11 +1,11 @@
package com.thebrokenrail.reliccraft.mixin;
import net.minecraft.advancement.criterion.Criteria;
import net.minecraft.advancement.criterion.Criterion;
import net.minecraft.advancement.criterion.Criterions;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Criterions.class)
@Mixin(Criteria.class)
public interface CriteriaRegistryHook {
@Invoker("register")
static <T extends Criterion<?>> T callRegister(T criterion) {

View File

@ -0,0 +1,15 @@
package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
import net.minecraft.client.world.ClientWorld;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(ClientWorld.class)
public abstract class MixinClientWorld extends MixinWorld {
@ModifyConstant(constant = @Constant(longValue = 1L), method = "tickTime")
public long tickTime(long value) {
return value * TimeDilaterItem.getTimeDilationFactor(getTimeSpeed());
}
}

View File

@ -1,19 +0,0 @@
package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.DefaultBiomeFeatures;
import net.minecraft.world.gen.GenerationStep;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@SuppressWarnings("unused")
@Mixin(DefaultBiomeFeatures.class)
public class MixinDefaultBiomeFeatures {
@Inject(at = @At("RETURN"), method = "addDefaultStructures")
private static void addDefaultStructures(Biome biome, CallbackInfo info) {
biome.addFeature(GenerationStep.Feature.SURFACE_STRUCTURES, RelicCraft.getConfiguredFeature(RelicCraft.TIME_TEMPLE_STRUCTURE_FEATURE));
}
}

View File

@ -13,11 +13,8 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
import org.spongepowered.asm.mixin.Mixin;
import java.util.Objects;
@SuppressWarnings("unused")
@Mixin(EnderPearlItem.class)
public class MixinEnderPearlItem extends Item {
@ -29,16 +26,15 @@ public class MixinEnderPearlItem extends Item {
public ActionResult useOnBlock(ItemUsageContext context) {
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
String dimension = Objects.requireNonNull(DimensionType.getId(world.getDimension().getType())).toString();
String dimension = world.getRegistryKey().toString();
BlockState state = world.getBlockState(pos);
PlayerEntity user = context.getPlayer();
if (!world.isClient()) {
assert user != null;
RelicCraft.playRelicSound(user);
}
if (user != null && state.getBlock() == RelicCraft.TELEPORTATION_BEACON_BLOCK && state.get(AbstractDragonEggHolderBlock.ACTIVE)) {
if (!world.isClient()) {
RelicCraft.playRelicSound(user);
}
CompoundTag tag = new CompoundTag();
tag.putInt("TargetX", pos.getX());
tag.putInt("TargetY", pos.getY());

View File

@ -2,32 +2,86 @@ package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("unused")
@Mixin(Entity.class)
public class MixinEntity implements TeleportationRestrictorBlock.TeleportingEntity {
public abstract class MixinEntity implements TeleportationRestrictorBlock.TeleportingEntity {
@Shadow
protected boolean inNetherPortal;
@Shadow
public abstract World getEntityWorld();
@Shadow
public abstract DataTracker getDataTracker();
@Unique
private int teleportCooldown = 0;
private static final byte DEFAULT_TELEPORT_COOLDOWN = 80;
@Unique
private static final TrackedData<Byte> TELEPORT_COOLDOWN = DataTracker.registerData(Entity.class, TrackedDataHandlerRegistry.BYTE);
@Inject(at = @At("RETURN"), method = "<init>")
public void init(EntityType<?> type, World world, CallbackInfo info) {
getDataTracker().startTracking(TELEPORT_COOLDOWN, (byte) 0);
}
@Override
public void resetTeleportCooldown() {
teleportCooldown = 5;
getDataTracker().set(TELEPORT_COOLDOWN, (byte) 0);
}
@Inject(at = @At("HEAD"), method = "tick")
public void tick(CallbackInfo info) {
if (teleportCooldown > 0) {
teleportCooldown--;
@Inject(at = @At("RETURN"), method = "baseTick")
public void baseTick(CallbackInfo info) {
updateNetherPortal();
byte data = getDataTracker().get(TELEPORT_COOLDOWN);
if (getEntityWorld() instanceof ServerWorld && data < DEFAULT_TELEPORT_COOLDOWN) {
data++;
getDataTracker().set(TELEPORT_COOLDOWN, data);
}
}
@Unique
private void updateNetherPortal() {
if (cannotTeleport()) {
inNetherPortal = false;
}
}
@Inject(at = @At("HEAD"), method = "canUsePortals", cancellable = true)
public void canUsePortals(CallbackInfoReturnable<Boolean> info) {
if (cannotTeleport()) {
info.setReturnValue(false);
}
}
@Override
public boolean cannotTeleport() {
return teleportCooldown > 0;
return getDataTracker().get(TELEPORT_COOLDOWN) < DEFAULT_TELEPORT_COOLDOWN;
}
@Inject(at = @At("HEAD"), method = "toTag")
public void toTag(CompoundTag tag, CallbackInfoReturnable<CompoundTag> info) {
tag.putByte("RelicCraftTeleportCooldown", getDataTracker().get(TELEPORT_COOLDOWN));
}
@Inject(at = @At("HEAD"), method = "fromTag")
public void fromTag(CompoundTag tag, CallbackInfo info) {
getDataTracker().set(TELEPORT_COOLDOWN, tag.getByte("RelicCraftTeleportCooldown"));
updateNetherPortal();
}
}

View File

@ -2,10 +2,10 @@ package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.chunk.ChunkGeneratorConfig;
import net.minecraft.world.gen.feature.LakeFeature;
import net.minecraft.world.gen.feature.SingleStateFeatureConfig;
import org.spongepowered.asm.mixin.Mixin;
@ -21,7 +21,7 @@ import java.util.Random;
@Mixin(LakeFeature.class)
public class MixinLakeFeature {
@Inject(at = @At("HEAD"), method = "generate", cancellable = true)
public void fixTimeTemple(IWorld world, ChunkGenerator<? extends ChunkGeneratorConfig> chunkGenerator, Random random, BlockPos blockPos, SingleStateFeatureConfig singleStateFeatureConfig, CallbackInfoReturnable<Boolean> info) {
public void fixTimeTemple(ServerWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, SingleStateFeatureConfig singleStateFeatureConfig, CallbackInfoReturnable<Boolean> info) {
List<Chunk> chunksToScan = new ArrayList<>();
chunksToScan.add(world.getChunk(blockPos));
chunksToScan.add(world.getChunk(blockPos.add(16, 0, 16)));
@ -34,7 +34,7 @@ public class MixinLakeFeature {
chunksToScan.add(world.getChunk(blockPos.add(-16, 0, 16)));
for (Chunk chunk : chunksToScan) {
if (!chunk.getStructureReferences(RelicCraft.TIME_TEMPLE_ID).isEmpty()) {
if (!chunk.getStructureReferences(RelicCraft.TIME_TEMPLE_STRUCTURE_FEATURE).isEmpty()) {
info.setReturnValue(false);
break;
}

View File

@ -1,41 +0,0 @@
package com.thebrokenrail.reliccraft.mixin;
import com.mojang.datafixers.DataFixer;
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.LevelProperties;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@SuppressWarnings("unused")
@Mixin(LevelProperties.class)
public class MixinLevelProperties implements TimeDilaterItem.DilatedWorld {
@Unique
private TimeDilaterItem.TimeSpeed timeSpeed = TimeDilaterItem.TimeSpeed.NORMAL;
@Inject(at = @At("RETURN"), method = "<init>(Lnet/minecraft/nbt/CompoundTag;Lcom/mojang/datafixers/DataFixer;ILnet/minecraft/nbt/CompoundTag;)V")
public void init(CompoundTag compoundTag, DataFixer dataFixer, int i, CompoundTag compoundTag2, CallbackInfo info) {
try {
timeSpeed = TimeDilaterItem.TimeSpeed.valueOf(compoundTag.getString("RelicCraftTimeSpeed"));
} catch (IllegalArgumentException ignored) {
}
}
@Inject(at = @At("RETURN"), method = "updateProperties")
public void updateProperties(CompoundTag levelTag, CompoundTag playerTag, CallbackInfo ci) {
levelTag.putString("RelicCraftTimeSpeed", timeSpeed.name());
}
@Override
public TimeDilaterItem.TimeSpeed getTimeSpeed() {
return timeSpeed;
}
@Override
public void setTimeSpeed(TimeDilaterItem.TimeSpeed timeSpeed) {
this.timeSpeed = timeSpeed;
}
}

View File

@ -1,5 +1,6 @@
package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
import net.minecraft.entity.LivingEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -8,10 +9,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("unused")
@Mixin(LivingEntity.class)
public class MixinLivingEntity extends MixinEntity {
public abstract class MixinLivingEntity {
@Inject(at = @At("HEAD"), method = "teleport", cancellable = true)
public void teleport(double x, double y, double z, boolean particleEffects, CallbackInfoReturnable<Boolean> info) {
if (cannotTeleport()) {
if (((TeleportationRestrictorBlock.TeleportingEntity) this).cannotTeleport()) {
info.setReturnValue(false);
}
}

View File

@ -1,27 +0,0 @@
package com.thebrokenrail.reliccraft.mixin;
import com.mojang.brigadier.CommandDispatcher;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.LocateCommand;
import net.minecraft.server.command.ServerCommandSource;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@SuppressWarnings("unused")
@Mixin(LocateCommand.class)
public abstract class MixinLocateCommand {
@Shadow
private static int execute(ServerCommandSource source, String structure) {
throw new UnsupportedOperationException();
}
@Inject(method = "register", at = @At(value = "RETURN"))
private static void onRegister(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo info) {
dispatcher.register(CommandManager.literal("locate").requires(source -> source.hasPermissionLevel(2))
.then(CommandManager.literal("RelicCraft_Time_Temple").executes(ctx -> execute(ctx.getSource(), RelicCraft.TIME_TEMPLE_ID))));
}
}

View File

@ -15,8 +15,8 @@ public abstract class MixinServerChunkManager {
@Shadow
public abstract World getWorld();
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameRules;getInt(Lnet/minecraft/world/GameRules$RuleKey;)I"), method = "tickChunks")
public int adjustRandomTickSpeed(GameRules gameRules, GameRules.RuleKey<GameRules.IntRule> rule) {
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameRules;getInt(Lnet/minecraft/world/GameRules$Key;)I"), method = "tickChunks")
public int adjustRandomTickSpeed(GameRules gameRules, GameRules.Key<GameRules.IntRule> rule) {
if (rule.equals(GameRules.RANDOM_TICK_SPEED)) {
return (int) (gameRules.getInt(rule) * TimeDilaterItem.getTimeDilationFactor(((TimeDilaterItem.DilatedWorld) getWorld()).getTimeSpeed()));
} else {

View File

@ -1,10 +1,17 @@
package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
import com.thebrokenrail.reliccraft.packet.UpdateTimeDilationS2CPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.function.BooleanSupplier;
@ -12,8 +19,31 @@ import java.util.function.BooleanSupplier;
@SuppressWarnings("unused")
@Mixin(ServerWorld.class)
public abstract class MixinServerWorld extends MixinWorld {
@Unique
private TimeDilaterItem.TimeSpeedState timeSpeedState;
@Inject(at = @At("RETURN"), method = "tick")
public void tick(BooleanSupplier shouldKeepTicking, CallbackInfo info) {
UpdateTimeDilationS2CPacket.send((ServerWorld) (Object) this, getTimeSpeed());
}
@ModifyConstant(constant = @Constant(longValue = 1L), method = "tickTime")
public long tickTime(long value) {
return value * TimeDilaterItem.getTimeDilationFactor(getTimeSpeed());
}
@Shadow
public abstract MinecraftServer getServer();
@Override
public void setTimeSpeed(TimeDilaterItem.TimeSpeed timeSpeed) {
TimeDilaterItem.TimeSpeedState state = getServer().getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TimeDilaterItem.TimeSpeedState::new, TimeDilaterItem.TIME_SPEED_KEY);
state.setTimeSpeed(timeSpeed);
getServer().getWorld(World.OVERWORLD).getPersistentStateManager().set(state);
}
@Override
public TimeDilaterItem.TimeSpeed getTimeSpeed() {
return getServer().getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TimeDilaterItem.TimeSpeedState::new, TimeDilaterItem.TIME_SPEED_KEY).getTimeSpeed();
}
}

View File

@ -1,8 +1,7 @@
package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.block.TeleportationRestrictorBlock;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.thrown.ThrownEnderpearlEntity;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.util.hit.HitResult;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -10,13 +9,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@SuppressWarnings("unused")
@Mixin(ThrownEnderpearlEntity.class)
@Mixin(EnderPearlEntity.class)
public class MixinThrownEnderpearlEntity {
@Inject(at = @At("HEAD"), method = "onCollision", cancellable = true)
public void onCollision(HitResult hitResult, CallbackInfo info) {
LivingEntity owner = ((ThrownEnderpearlEntity) (Object) this).getOwner();
if (owner != null && ((TeleportationRestrictorBlock.TeleportingEntity) owner).cannotTeleport()) {
((ThrownEnderpearlEntity) (Object) this).remove();
if (((TeleportationRestrictorBlock.TeleportingEntity) this).cannotTeleport()) {
((EnderPearlEntity) (Object) this).remove();
info.cancel();
}
}

View File

@ -2,12 +2,9 @@ package com.thebrokenrail.reliccraft.mixin;
import com.thebrokenrail.reliccraft.item.TimeDilaterItem;
import net.minecraft.world.World;
import net.minecraft.world.level.LevelProperties;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.Unique;
@SuppressWarnings("unused")
@Mixin(World.class)
@ -15,25 +12,19 @@ public abstract class MixinWorld implements TimeDilaterItem.DilatedWorld {
@Shadow
public abstract boolean isClient();
@Shadow
@Final
protected LevelProperties properties;
@Unique
private TimeDilaterItem.TimeSpeed timeSpeed = TimeDilaterItem.TimeSpeed.NORMAL;
@Shadow
public abstract long getTime();
@ModifyConstant(constant = @Constant(longValue = 1L), method = "tickTime")
public long tickTime(long value) {
return value * TimeDilaterItem.getTimeDilationFactor(getTimeSpeed());
}
@Override
public void setTimeSpeed(TimeDilaterItem.TimeSpeed timeSpeed) {
((TimeDilaterItem.DilatedWorld) properties).setTimeSpeed(timeSpeed);
this.timeSpeed = timeSpeed;
}
@Override
public TimeDilaterItem.TimeSpeed getTimeSpeed() {
return ((TimeDilaterItem.DilatedWorld) properties).getTimeSpeed();
return timeSpeed;
}
}

View File

@ -0,0 +1,16 @@
package com.thebrokenrail.reliccraft.mixin;
import net.minecraft.client.item.ModelPredicateProvider;
import net.minecraft.client.item.ModelPredicateProviderRegistry;
import net.minecraft.item.Item;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(ModelPredicateProviderRegistry.class)
public interface ModelPredicateProviderRegistryHook {
@Invoker
static void callRegister(Item item, Identifier id, ModelPredicateProvider provider) {
throw new UnsupportedOperationException();
}
}

View File

@ -10,9 +10,9 @@ import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
import net.minecraft.world.World;
@SuppressWarnings("unused")

View File

@ -11,8 +11,8 @@ import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.SpecialCraftingRecipe;
import net.minecraft.util.DefaultedList;
import net.minecraft.util.Identifier;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.world.World;
import java.util.Random;
@ -27,8 +27,8 @@ public class RevealRelicRecipe extends SpecialCraftingRecipe {
ItemStack itemStack = ItemStack.EMPTY;
int netherStar = 0;
for (int i = 0; i < craftingInventory.getInvSize(); ++i) {
ItemStack itemStack2 = craftingInventory.getInvStack(i);
for (int i = 0; i < craftingInventory.size(); ++i) {
ItemStack itemStack2 = craftingInventory.getStack(i);
if (!itemStack2.isEmpty()) {
if (itemStack2.getItem() instanceof RelicItem) {
if (!itemStack.isEmpty()) {
@ -51,8 +51,8 @@ public class RevealRelicRecipe extends SpecialCraftingRecipe {
public ItemStack craft(CraftingInventory craftingInventory) {
ItemStack itemStack = ItemStack.EMPTY;
for (int i = 0; i < craftingInventory.getInvSize(); i++) {
ItemStack itemStack2 = craftingInventory.getInvStack(i);
for (int i = 0; i < craftingInventory.size(); i++) {
ItemStack itemStack2 = craftingInventory.getStack(i);
if (!itemStack2.isEmpty()) {
Item item = itemStack2.getItem();
if (item instanceof RelicItem) {
@ -92,9 +92,9 @@ public class RevealRelicRecipe extends SpecialCraftingRecipe {
@Override
public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inventory) {
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(inventory.getInvSize(), ItemStack.EMPTY);
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(inventory.size(), ItemStack.EMPTY);
for (int i = 0; i < defaultedList.size(); i++) {
ItemStack stack = inventory.getInvStack(i);
ItemStack stack = inventory.getStack(i);
if (stack.getItem().hasRecipeRemainder()) {
defaultedList.set(i, new ItemStack(stack.getItem().getRecipeRemainder()));
} else if (stack.getItem() == Items.NETHER_STAR && !stack.damage(1, new Random(), null)) {

View File

@ -8,8 +8,8 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapelessRecipe;
import net.minecraft.util.DefaultedList;
import net.minecraft.util.Identifier;
import net.minecraft.util.collection.DefaultedList;
import java.util.Random;
@ -39,9 +39,9 @@ public class TimeDilaterRecipe extends ShapelessRecipe {
@Override
public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inventory) {
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(inventory.getInvSize(), ItemStack.EMPTY);
DefaultedList<ItemStack> defaultedList = DefaultedList.ofSize(inventory.size(), ItemStack.EMPTY);
for (int i = 0; i < defaultedList.size(); i++) {
ItemStack stack = inventory.getInvStack(i);
ItemStack stack = inventory.getStack(i);
if (stack.getItem() == Items.NETHER_STAR && !stack.damage(1, new Random(), null) || stack.getItem() == RelicCraft.TIME_DILATER_ITEM) {
defaultedList.set(i, stack.copy());
}

View File

@ -1,34 +1,50 @@
package com.thebrokenrail.reliccraft.structure;
import com.mojang.datafixers.Dynamic;
import com.thebrokenrail.reliccraft.RelicCraft;
import net.minecraft.world.gen.feature.AbstractTempleFeature;
import com.mojang.serialization.Codec;
import net.minecraft.structure.StructureManager;
import net.minecraft.structure.StructureStart;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeSource;
import net.minecraft.world.gen.ChunkRandom;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import java.util.function.Function;
public class TimeTempleFeature extends AbstractTempleFeature<DefaultFeatureConfig> {
public TimeTempleFeature(Function<Dynamic<?>, ? extends DefaultFeatureConfig> configFactory) {
super(configFactory);
public class TimeTempleFeature extends StructureFeature<DefaultFeatureConfig> {
public TimeTempleFeature(Codec<DefaultFeatureConfig> codec) {
super(codec);
}
@Override
protected int getSeedModifier() {
return 0;
public StructureStartFactory<DefaultFeatureConfig> getStructureStartFactory() {
return Start::new;
}
@Override
public StructureStartFactory getStructureStartFactory() {
return TimeTempleStructureStart::new;
protected boolean shouldStartAt(ChunkGenerator chunkGenerator, BiomeSource biomeSource, long l, ChunkRandom chunkRandom, int i, int j, Biome biome, ChunkPos chunkPos, DefaultFeatureConfig defaultFeatureConfig) {
int k = i >> 4;
int m = j >> 4;
chunkRandom.setSeed((long) (k ^ m << 4) ^ l);
chunkRandom.nextInt();
return chunkRandom.nextInt(5) == 0;
}
@Override
public String getName() {
return RelicCraft.TIME_TEMPLE_ID;
}
public static class Start extends StructureStart<DefaultFeatureConfig> {
public Start(StructureFeature<DefaultFeatureConfig> feature, int chunkX, int chunkZ, BlockBox box, int references, long seed) {
super(feature, chunkX, chunkZ, box, references, seed);
}
@Override
public int getRadius() {
return 8;
@Override
public void init(ChunkGenerator chunkGenerator, StructureManager structureManager, int x, int z, Biome biome, DefaultFeatureConfig featureConfig) {
int i = x * 16;
int j = z * 16;
BlockPos blockPos = new BlockPos(i, 90, j);
BlockRotation blockRotation = BlockRotation.values()[random.nextInt(BlockRotation.values().length)];
TimeTempleGenerator.addPieces(structureManager, blockPos, blockRotation, children);
setBoundingBoxFromChildren();
}
}
}

View File

@ -19,7 +19,9 @@ import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.Heightmap;
import net.minecraft.world.IWorld;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import java.util.Collection;
@ -52,7 +54,7 @@ public class TimeTempleGenerator {
private void initializeStructureData(StructureManager manager) {
Structure structure = manager.getStructureOrBlank(template);
StructurePlacementData structurePlacementData = new StructurePlacementData().setRotation(rotation).setMirrored(BlockMirror.NONE).setIgnoreEntities(true).addProcessor(BlockIgnoreStructureProcessor.IGNORE_STRUCTURE_BLOCKS);
StructurePlacementData structurePlacementData = new StructurePlacementData().setRotation(rotation).setMirror(BlockMirror.NONE).setIgnoreEntities(true).addProcessor(BlockIgnoreStructureProcessor.IGNORE_STRUCTURE_BLOCKS);
setStructureData(structure, pos, structurePlacementData);
}
@ -64,39 +66,31 @@ public class TimeTempleGenerator {
}
@Override
public boolean generate(IWorld world, ChunkGenerator<?> generator, Random random, BlockBox box, ChunkPos chunkPos) {
int yHeight = 0;
int area = 0;
for (int x = getBoundingBox().minX; x <= getBoundingBox().maxX; x++) {
for (int z = getBoundingBox().minZ; z <= getBoundingBox().maxZ; z++) {
yHeight = yHeight + world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, x, z);
area++;
}
}
yHeight = yHeight / area;
public boolean generate(ServerWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, Random random, BlockBox boundingBox, ChunkPos chunkPos, BlockPos blockPos) {
int yHeight = world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, this.pos.getX() + 5, this.pos.getZ() + 5);
BlockPos originalPos = pos;
pos = pos.add(0, yHeight - 90, 0);
boolean result = super.generate(world, generator, random, box, chunkPos);
boolean result = super.generate(world, structureAccessor, chunkGenerator, random, boundingBox, chunkPos, blockPos);
if (result) {
for (int x = getBoundingBox().minX; x <= getBoundingBox().maxX; x++) {
for (int y = getBoundingBox().minY; y <= getBoundingBox().maxY; y++) {
for (int z = getBoundingBox().minZ; z <= getBoundingBox().maxZ; z++) {
BlockPos blockPos = new BlockPos(x, y, z);
if (box.contains(blockPos)) {
BlockState state = world.getBlockState(blockPos);
BlockPos newPos = new BlockPos(x, y, z);
if (boundingBox.contains(newPos)) {
BlockState state = world.getBlockState(newPos);
boolean damaged = random.nextFloat() < 0.6f;
if (damaged) {
if (state.getBlock() == Blocks.STONE_BRICKS) {
boolean mossy = random.nextFloat() < 0.5f;
world.setBlockState(blockPos, convertState(state, mossy ? Blocks.MOSSY_STONE_BRICKS : Blocks.CRACKED_STONE_BRICKS), 3);
} else if (world.getBlockState(blockPos).getBlock() == Blocks.STONE_BRICK_STAIRS) {
world.setBlockState(blockPos, convertState(state, Blocks.MOSSY_STONE_BRICK_STAIRS), 3);
} else if (world.getBlockState(blockPos).getBlock() == Blocks.STONE_BRICK_SLAB) {
world.setBlockState(blockPos, convertState(state, Blocks.MOSSY_STONE_BRICK_SLAB), 3);
world.setBlockState(newPos, convertState(state, mossy ? Blocks.MOSSY_STONE_BRICKS : Blocks.CRACKED_STONE_BRICKS), 3);
} else if (world.getBlockState(newPos).getBlock() == Blocks.STONE_BRICK_STAIRS) {
world.setBlockState(newPos, convertState(state, Blocks.MOSSY_STONE_BRICK_STAIRS), 3);
} else if (world.getBlockState(newPos).getBlock() == Blocks.STONE_BRICK_SLAB) {
world.setBlockState(newPos, convertState(state, Blocks.MOSSY_STONE_BRICK_SLAB), 3);
}
}
}
@ -121,7 +115,7 @@ public class TimeTempleGenerator {
}
@Override
protected void handleMetadata(String metadata, BlockPos pos, IWorld world, Random random, BlockBox boundingBox) {
protected void handleMetadata(String metadata, BlockPos pos, WorldAccess world, Random random, BlockBox boundingBox) {
}
}
}

View File

@ -1,26 +0,0 @@
package com.thebrokenrail.reliccraft.structure;
import net.minecraft.structure.StructureManager;
import net.minecraft.structure.StructureStart;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.StructureFeature;
public class TimeTempleStructureStart extends StructureStart {
public TimeTempleStructureStart(StructureFeature<?> feature, int chunkX, int chunkZ, BlockBox box, int references, long l) {
super(feature, chunkX, chunkZ, box, references, l);
}
@Override
public void initialize(ChunkGenerator<?> chunkGenerator, StructureManager structureManager, int x, int z, Biome biome) {
int i = x * 16;
int j = z * 16;
BlockPos blockPos = new BlockPos(i, 90, j);
BlockRotation blockRotation = BlockRotation.values()[random.nextInt(BlockRotation.values().length)];
TimeTempleGenerator.addPieces(structureManager, blockPos, blockRotation, children);
setBoundingBoxFromChildren();
}
}

View File

@ -36,6 +36,8 @@
"item.reliccraft.tooltip.targeted_ender_pearl.y": "Y: %s",
"item.reliccraft.tooltip.targeted_ender_pearl.z": "Z: %s",
"item.reliccraft.tooltip.targeted_ender_pearl.dimension": "Dimension: %s",
"item.reliccraft.generate_relic": "Creative Relic Generator",
"item.reliccraft.generate_relic.tooltip": "Generates A Random Relic On Use",
"text.reliccraft.relic.action.heal_action": "Heal",
"text.reliccraft.relic.action.bedrock_action": "Turn To Bedrock",
"text.reliccraft.relic.action.gold_action": "Turn Coal To Gold",
@ -69,5 +71,6 @@
"advancements.reliccraft.duplicate_time_dilater.description": "Duplicate a Time Dilater",
"text.reliccraft.dimension.minecraft.overworld": "The Overworld",
"text.reliccraft.dimension.minecraft.the_nether": "The Nether",
"text.reliccraft.dimension.minecraft.the_end": "The End"
"text.reliccraft.dimension.minecraft.the_end": "The End",
"itemGroup.reliccraft.item_group": "RelicCraft"
}

View File

@ -0,0 +1,3 @@
{
"parent": "minecraft:item/blaze_rod"
}

View File

@ -1,7 +1,7 @@
{
"display": {
"icon": {
"item": "minecraft:ender_chest"
"item": "reliccraft:time_dilater"
},
"title": {
"translate": "advancements.reliccraft.root.title"
@ -21,7 +21,7 @@
"conditions": {
"items": [
{
"tag": "reliccraft:items"
"tag": "reliccraft:advancement_trigger_items"
}
]
}

View File

@ -5,6 +5,7 @@
"reliccraft:time_dilater",
"reliccraft:teleportation_restrictor",
"reliccraft:teleportation_beacon",
"reliccraft:targeted_ender_pearl"
"reliccraft:targeted_ender_pearl",
"minecraft:dragon_egg"
]
}

View File

@ -29,6 +29,12 @@
"depends": {
"fabricloader": ">=0.7.4",
"fabric": "*",
"minecraft": "1.15.x"
"minecraft": "1.16.x"
},
"custom": {
"modupdater": {
"strategy": "curseforge",
"projectID": 373074
}
}
}

View File

@ -8,20 +8,19 @@
"mixins": [
"CriteriaRegistryHook",
"MixinBlockItem",
"MixinDefaultBiomeFeatures",
"MixinClientWorld",
"MixinEnderDragonFight",
"MixinEnderPearlItem",
"MixinEntity",
"MixinItemStack",
"MixinLakeFeature",
"MixinLevelProperties",
"MixinLivingEntity",
"MixinLocateCommand",
"MixinNetherStarItem",
"MixinServerChunkManager",
"MixinServerWorld",
"MixinThrownEnderpearlEntity",
"MixinWorld"
"MixinWorld",
"ModelPredicateProviderRegistryHook"
],
"injectors": {
"defaultRequire": 1