mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-22 15:47:57 -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",
|
||||
"DefaultAttributeRegistryMixin",
|
||||
"MaterialBuilderAccessor",
|
||||
"MixinBlock"
|
||||
"MixinBlock",
|
||||
"PointOfInterestTypeAccessor",
|
||||
"VillagerProfessionAccessor"
|
||||
],
|
||||
"client": [
|
||||
"ModelPredicateProviderRegistryAccessor",
|
||||
|
|
Loading…
Reference in a new issue