mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-26 17:46:25 -05:00
Add object builders to simplify the process of creating Villager professions (#493)
* Add Object builders for simplifying the process of creating villager professions and point of interest types. * Move everything to new object-builders-api * flatten a bit down * a few javadoc changes * More JD tweaks
This commit is contained in:
parent
da175ad6ad
commit
2521f6a319
5 changed files with 365 additions and 1 deletions
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.object.builder.v1.villager;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.client.render.entity.feature.VillagerResourceMetadata;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.village.TradeOffers;
|
||||||
|
import net.minecraft.village.VillagerProfession;
|
||||||
|
import net.minecraft.world.poi.PointOfInterestType;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.mixin.object.builder.VillagerProfessionAccessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows for the creation of new {@link VillagerProfession}s.
|
||||||
|
*
|
||||||
|
* <p>The texture for the villagers are located at <code>assets/IDENTIFIER_NAMESPACE/textures/entity/villager/profession/IDENTIFIER_PATH.png</code>
|
||||||
|
*
|
||||||
|
* <p>A corresponding <code>IDENTIFIER_PATH.mcmeta</code> file exits in the same directory to define properties such as the {@link VillagerResourceMetadata.HatType HatType} this profession would use.
|
||||||
|
*
|
||||||
|
* <p>Note this does not register any trades to these villagers. To register trades, add a new entry with your profession as the key to {@link TradeOffers#PROFESSION_TO_LEVELED_TRADE}.
|
||||||
|
*/
|
||||||
|
public final class VillagerProfessionBuilder {
|
||||||
|
private final ImmutableSet.Builder<Item> gatherableItemsBuilder = ImmutableSet.builder();
|
||||||
|
private final ImmutableSet.Builder<Block> secondaryJobSiteBlockBuilder = ImmutableSet.builder();
|
||||||
|
private Identifier identifier;
|
||||||
|
private PointOfInterestType pointOfInterestType;
|
||||||
|
/* @Nullable */
|
||||||
|
private SoundEvent workSoundEvent;
|
||||||
|
|
||||||
|
private VillagerProfessionBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a builder instance to allow for creation of a {@link VillagerProfession}.
|
||||||
|
* @return A new builder.
|
||||||
|
*/
|
||||||
|
static VillagerProfessionBuilder create() {
|
||||||
|
return new VillagerProfessionBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Identifier used to identify this villager profession.
|
||||||
|
*
|
||||||
|
* @param id The identifier to assign to this profession.
|
||||||
|
* @return this builder
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder id(Identifier id) {
|
||||||
|
this.identifier = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PointOfInterestType} the Villager of this profession will search for when finding a workstation.
|
||||||
|
*
|
||||||
|
* @param type The {@link PointOfInterestType} the Villager will attempt to find.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder workstation(PointOfInterestType type) {
|
||||||
|
this.pointOfInterestType = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Items that a Villager may harvest in this profession.
|
||||||
|
*
|
||||||
|
* <p>In Vanilla, this is used by the farmer to define what type of crops the farmer can harvest.
|
||||||
|
*
|
||||||
|
* @param items Items harvestable by this profession.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder harvestableItems(Item... items) {
|
||||||
|
this.gatherableItemsBuilder.add(items);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Items that a Villager may harvest in this profession.
|
||||||
|
*
|
||||||
|
* <p>In Vanilla, this is used by the farmer to define what type of crops the farmer can harvest.
|
||||||
|
*
|
||||||
|
* @param items Items harvestable by this profession.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder harvestableItems(Iterable<Item> items) {
|
||||||
|
this.gatherableItemsBuilder.addAll(items);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of blocks blocks which may suffice as a secondary job site for a Villager.
|
||||||
|
*
|
||||||
|
* <p>In Vanilla, this is used by the {@link VillagerProfession#FARMER Farmer} to stay near {@link Blocks#FARMLAND Farmland} when at it's job site.
|
||||||
|
*
|
||||||
|
* @param blocks Collection of secondary job site blocks.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder secondaryJobSites(Block... blocks) {
|
||||||
|
this.secondaryJobSiteBlockBuilder.add(blocks);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of blocks blocks which may suffice as a secondary job site for a Villager.
|
||||||
|
*
|
||||||
|
* <p>In Vanilla, this is used by the {@link VillagerProfession#FARMER Farmer} to stay near {@link Blocks#FARMLAND Farmland} when at it's job site.
|
||||||
|
*
|
||||||
|
* @param blocks Collection of secondary job site blocks.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder secondaryJobSites(Iterable<Block> blocks) {
|
||||||
|
this.secondaryJobSiteBlockBuilder.addAll(blocks);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the sound made when a Villager works.
|
||||||
|
*
|
||||||
|
* @param workSoundEvent The {@link SoundEvent} to be played.
|
||||||
|
* @return this builder.
|
||||||
|
*/
|
||||||
|
public VillagerProfessionBuilder workSound(/* @Nullable */ SoundEvent workSoundEvent) {
|
||||||
|
this.workSoundEvent = workSoundEvent;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the {@link VillagerProfession}.
|
||||||
|
*
|
||||||
|
* @return a new {@link VillagerProfession}.
|
||||||
|
* @throws IllegalStateException if the builder is missing an {@link Identifier id} and {@link PointOfInterestType workstation}.
|
||||||
|
*/
|
||||||
|
public VillagerProfession build() {
|
||||||
|
checkState(this.identifier != null, "An Identifier is required to build a new VillagerProfession.");
|
||||||
|
checkState(this.pointOfInterestType != null, "A PointOfInterestType is required to build a new VillagerProfession.");
|
||||||
|
return VillagerProfessionAccessor.create(this.identifier.toString(), this.pointOfInterestType, this.gatherableItemsBuilder.build(), this.secondaryJobSiteBlockBuilder.build(), this.workSoundEvent);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.object.builder.v1.world.poi;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.poi.PointOfInterest;
|
||||||
|
import net.minecraft.world.poi.PointOfInterestType;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.mixin.object.builder.PointOfInterestTypeAccessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides utilities to create a {@link PointOfInterestType}.
|
||||||
|
*
|
||||||
|
* <p>A point of interest is typically used by villagers to specify their workstation blocks, meeting zones and homes.
|
||||||
|
* Points of interest are also used by bees to specify where their bee hive is and nether portals to find existing portals.
|
||||||
|
*/
|
||||||
|
public final class PointOfInterestHelper {
|
||||||
|
private PointOfInterestHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and registers a {@link PointOfInterestType}.
|
||||||
|
*
|
||||||
|
* @param id The id of this {@link PointOfInterestType}.
|
||||||
|
* @param ticketCount the amount of tickets.
|
||||||
|
* @param searchDistance the search distance.
|
||||||
|
* @param blocks all the blocks where a {@link PointOfInterest} of this type will be present.
|
||||||
|
* @return a new {@link PointOfInterestType}.
|
||||||
|
*/
|
||||||
|
public static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Block... blocks) {
|
||||||
|
final ImmutableSet.Builder<BlockState> builder = ImmutableSet.builder();
|
||||||
|
|
||||||
|
for (Block block : blocks) {
|
||||||
|
builder.addAll(block.getStateManager().getStates());
|
||||||
|
}
|
||||||
|
|
||||||
|
return register(id, ticketCount, searchDistance, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and registers a {@link PointOfInterestType}.
|
||||||
|
*
|
||||||
|
* @param id The id of this {@link PointOfInterestType}.
|
||||||
|
* @param ticketCount the amount of tickets.
|
||||||
|
* @param completionCondition a {@link Predicate} which determines if two {@link PointOfInterestType}s are the same.
|
||||||
|
* @param searchDistance the search distance.
|
||||||
|
* @param blocks all blocks where a {@link PointOfInterest} of this type will be present
|
||||||
|
* @return a new {@link PointOfInterestType}.
|
||||||
|
*/
|
||||||
|
public static PointOfInterestType register(Identifier id, int ticketCount, Predicate<PointOfInterestType> completionCondition, int searchDistance, Block... blocks) {
|
||||||
|
final ImmutableSet.Builder<BlockState> builder = ImmutableSet.builder();
|
||||||
|
|
||||||
|
for (Block block : blocks) {
|
||||||
|
builder.addAll(block.getStateManager().getStates());
|
||||||
|
}
|
||||||
|
|
||||||
|
return register(id, ticketCount, completionCondition, searchDistance, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and registers a {@link PointOfInterestType}.
|
||||||
|
*
|
||||||
|
* @param id the id of this {@link PointOfInterestType}.
|
||||||
|
* @param ticketCount the amount of tickets.
|
||||||
|
* @param searchDistance the search distance.
|
||||||
|
* @param blocks all {@link BlockState block states} where a {@link PointOfInterest} of this type will be present
|
||||||
|
* @return a new {@link PointOfInterestType}.
|
||||||
|
*/
|
||||||
|
public static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Iterable<BlockState> blocks) {
|
||||||
|
final ImmutableSet.Builder<BlockState> builder = ImmutableSet.builder();
|
||||||
|
|
||||||
|
return register(id, ticketCount, searchDistance, builder.addAll(blocks).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and registers a {@link PointOfInterestType}.
|
||||||
|
*
|
||||||
|
* @param id the id of this {@link PointOfInterestType}.
|
||||||
|
* @param ticketCount the amount of tickets.
|
||||||
|
* @param typePredicate a {@link Predicate} which determines if two {@link PointOfInterestType}s are the same.
|
||||||
|
* @param searchDistance the search distance.
|
||||||
|
* @param states all {@link BlockState block states} where a {@link PointOfInterest} of this type will be present
|
||||||
|
* @return a new {@link PointOfInterestType}.
|
||||||
|
*/
|
||||||
|
public static PointOfInterestType register(Identifier id, int ticketCount, Predicate<PointOfInterestType> typePredicate, int searchDistance, Iterable<BlockState> states) {
|
||||||
|
final ImmutableSet.Builder<BlockState> builder = ImmutableSet.builder();
|
||||||
|
|
||||||
|
return register(id, ticketCount, typePredicate, searchDistance, builder.addAll(states).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERNAL METHODS
|
||||||
|
|
||||||
|
private static PointOfInterestType register(Identifier id, int ticketCount, int searchDistance, Set<BlockState> states) {
|
||||||
|
return Registry.register(Registry.POINT_OF_INTEREST_TYPE, id, PointOfInterestTypeAccessor.callSetup(
|
||||||
|
PointOfInterestTypeAccessor.callCreate(id.toString(), states, ticketCount, searchDistance)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PointOfInterestType register(Identifier id, int ticketCount, Predicate<PointOfInterestType> typePredicate, int searchDistance, Set<BlockState> states) {
|
||||||
|
return Registry.register(Registry.POINT_OF_INTEREST_TYPE, id, PointOfInterestTypeAccessor.callSetup(
|
||||||
|
PointOfInterestTypeAccessor.callCreate(id.toString(), states, ticketCount, typePredicate, searchDistance)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.mixin.object.builder;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.world.poi.PointOfInterestType;
|
||||||
|
|
||||||
|
@Mixin(PointOfInterestType.class)
|
||||||
|
public interface PointOfInterestTypeAccessor {
|
||||||
|
@Invoker("<init>")
|
||||||
|
static PointOfInterestType callCreate(String id, Set<BlockState> blockStates, int ticketCount, Predicate<PointOfInterestType> typePredicate, int searchDistance) {
|
||||||
|
throw new AssertionError("Untransformed Accessor!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Invoker("<init>")
|
||||||
|
static PointOfInterestType callCreate(String id, Set<BlockState> blockStates, int ticketCount, int searchDistance) {
|
||||||
|
throw new AssertionError("Untransformed Accessor!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Invoker("setup")
|
||||||
|
static PointOfInterestType callSetup(PointOfInterestType pointOfInterestType) {
|
||||||
|
throw new AssertionError("Untransformed Accessor!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.mixin.object.builder;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.village.VillagerProfession;
|
||||||
|
import net.minecraft.world.poi.PointOfInterestType;
|
||||||
|
|
||||||
|
@Mixin(VillagerProfession.class)
|
||||||
|
public interface VillagerProfessionAccessor {
|
||||||
|
@Invoker("<init>")
|
||||||
|
static VillagerProfession create(String id, PointOfInterestType type, ImmutableSet<Item> gatherableItems, ImmutableSet<Block> secondaryJobSites, /* @Nullable */ SoundEvent soundEvent) {
|
||||||
|
throw new AssertionError("Untransformed accessor!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,9 @@
|
||||||
"DefaultAttributeRegistryAccessor",
|
"DefaultAttributeRegistryAccessor",
|
||||||
"DefaultAttributeRegistryMixin",
|
"DefaultAttributeRegistryMixin",
|
||||||
"MaterialBuilderAccessor",
|
"MaterialBuilderAccessor",
|
||||||
"MixinBlock"
|
"MixinBlock",
|
||||||
|
"PointOfInterestTypeAccessor",
|
||||||
|
"VillagerProfessionAccessor"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"ModelPredicateProviderRegistryAccessor",
|
"ModelPredicateProviderRegistryAccessor",
|
||||||
|
|
Loading…
Reference in a new issue