Skip to content

Commit

Permalink
Implement new TradeOffer API and re-add Flardians
Browse files Browse the repository at this point in the history
Flardians is the proof of concept if you will for verifying usability
and functionality. Some registry events are still required, but the
overall trade offer generation is verified to be functional.

Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
  • Loading branch information
gabizou committed Dec 7, 2020
1 parent 614c6b7 commit 9128b15
Show file tree
Hide file tree
Showing 18 changed files with 456 additions and 231 deletions.
Expand Up @@ -52,6 +52,19 @@ public static void register(final DataProviderRegistrator registrator) {
.create(Keys.PROFESSION_TYPE)
.get(h -> (ProfessionType) h.getVillagerData().getProfession())
.set((h, v) -> h.setVillagerData(h.getVillagerData().withProfession((VillagerProfession) v)))
.create(Keys.EXPERIENCE)
.get(VillagerEntity::getXp)
.set(VillagerEntity::setXp)
.delete(h -> h.setXp(0))
.create(Keys.EXPERIENCE_LEVEL)
.get(h -> h.getVillagerData().getLevel())
.setAnd((h, v) -> {
if (v < 1) {
return false;
}
h.setVillagerData(h.getVillagerData().withLevel(v));
return true;
})

This comment has been minimized.

Copy link
@gabizou

gabizou Dec 7, 2020

Author Member

@Grinch, @Zidane mentioned you could have something to do with re-implementing the experience handling for villagers? We found that the ChangeJobBrain will re-associate the profession if a villager has it set without a sufficient experience level, but there's also a fair amount of experience before/after leveling we can expose (there's a hard coded array of experience required between levels, and caps at 5).

.create(Keys.TRADE_OFFERS)
.get(h -> h.getOffers().stream().map(TradeOffer.class::cast).collect(Collectors.toList()))
.set((h, v) -> h.setOffers(v.stream().map(MerchantOffer.class::cast).collect(Collectors.toCollection(MerchantOffers::new))))
Expand Down
Expand Up @@ -58,14 +58,11 @@
import org.spongepowered.common.util.PrettyPrinter;

import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;
import java.util.Set;

public final class SpongeItemStackBuilder extends AbstractDataBuilder<ItemStack> implements ItemStack.Builder {
@Nullable private Set<Mutable<?, ?>> itemDataSet;
private ItemType type;
private int quantity;
@Nullable private LinkedHashMap<Key<?>, Object> keyValues;
Expand Down Expand Up @@ -107,7 +104,6 @@ public <V> ItemStack.Builder add(final Key<? extends Value<V>> key, final V valu
@Override
public ItemStack.Builder fromItemStack(final ItemStack itemStack) {
checkNotNull(itemStack, "Item stack cannot be null");
this.itemDataSet = new HashSet<>();
// Assumes the item stack's values don't need to be validated
this.type = itemStack.getType();
this.quantity = itemStack.getQuantity();
Expand Down Expand Up @@ -300,7 +296,6 @@ protected Optional<ItemStack> buildContent(final DataView container) throws Inva
public ItemStack.Builder reset() {
this.type = null;
this.quantity = 1;
this.itemDataSet = new HashSet<>();
this.compound = null;
return this;
}
Expand Down
Expand Up @@ -25,90 +25,121 @@
package org.spongepowered.common.item.generation;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.data.Key;
import org.spongepowered.api.data.value.Value;
import org.spongepowered.api.item.ItemType;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.item.inventory.ItemStackGenerator;
import org.spongepowered.api.util.weighted.WeightedTable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.StringJoiner;
import java.util.function.BiConsumer;

import javax.annotation.Nullable;

public final class SpongeItemStackGenerator implements ItemStackGenerator {

@Nullable final ItemType baseType;
final WeightedTable<ItemType> baseType;
final Map<Key<@NonNull ?>, Object> keyValues;
final List<BiConsumer<ItemStack.Builder, Random>> biConsumers;

private SpongeItemStackGenerator(org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder builder) {
SpongeItemStackGenerator(final org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder builder) {
this.biConsumers = ImmutableList.copyOf(builder.consumers);
this.baseType = builder.baseItem;
this.keyValues = builder.keyValues == null ? Collections.emptyMap() : builder.keyValues;
}

@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public ItemStack apply(Random random) {
public ItemStack apply(final Random random) {
final ItemStack.Builder builder = ItemStack.builder();
if (this.baseType != null) {
builder.itemType(this.baseType);
}
final List<ItemType> itemTypes = this.baseType.get(random);
builder.itemType(itemTypes.get(random.nextInt(itemTypes.size())));
this.biConsumers.forEach(builderRandomBiConsumer -> builderRandomBiConsumer.accept(builder, random));
this.keyValues.forEach((k, v) -> builder.add((Key) k, v));
return builder.build();
}

@Override
public boolean equals(Object o) {
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
SpongeItemStackGenerator that = (SpongeItemStackGenerator) o;
return Objects.equal(this.baseType, that.baseType) &&
Objects.equal(this.biConsumers, that.biConsumers);
final SpongeItemStackGenerator that = (SpongeItemStackGenerator) o;
return Objects.equals(this.baseType, that.baseType) &&
Objects.equals(this.biConsumers, that.biConsumers);
}

@Override
public int hashCode() {
return Objects.hashCode(this.baseType, this.biConsumers);
return Objects.hash(this.baseType, this.biConsumers);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("baseType", this.baseType)
.add("biConsumers", this.biConsumers)
.toString();
return new StringJoiner(
", ",
SpongeItemStackGenerator.class.getSimpleName() + "[",
"]"
)
.add("baseType=" + this.baseType)
.add("keyValues=" + this.keyValues)
.add("biConsumers=" + this.biConsumers)
.toString();
}

public static final class Builder implements ItemStackGenerator.Builder {

final List<BiConsumer<ItemStack.Builder, Random>> consumers = new ArrayList<>();
@Nullable ItemType baseItem;
@MonotonicNonNull WeightedTable<ItemType> baseItem;
@Nullable LinkedHashMap<Key<@NonNull ?>, Object> keyValues;

@Override
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder add(final BiConsumer<ItemStack.Builder, Random> consumer) {
this.consumers.add(Objects.requireNonNull(consumer, "Consumer cannot be null!"));
return this;
}

@Override
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder add(BiConsumer<ItemStack.Builder, Random> consumer) {
this.consumers.add(checkNotNull(consumer, "Consumer cannot be null!"));
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder addAll(final Collection<BiConsumer<ItemStack.Builder, Random>> collection) {
this.consumers.addAll(Objects.requireNonNull(collection, "Collecton cannot be null!"));
return this;
}

@Override
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder addAll(Collection<BiConsumer<ItemStack.Builder, Random>> collection) {
this.consumers.addAll(checkNotNull(collection, "Collecton cannot be null!"));
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder baseItem(final ItemType itemType) {
this.baseItem = new WeightedTable<>();
this.baseItem.add(itemType, 1);
return this;
}

@Override
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder baseItem(ItemType itemType) {
this.baseItem = itemType;
public ItemStackGenerator.Builder baseItem(final WeightedTable<ItemType> itemType) {
this.baseItem = Objects.requireNonNull(itemType, "Item table cannot be null");
return this;
}

@Override
public <V> ItemStackGenerator.Builder add(final Key<? extends Value<V>> key, final V value) {
if (this.keyValues == null) {
this.keyValues = new LinkedHashMap<>();
}
this.keyValues.put(key, value);
return this;
}

Expand All @@ -119,22 +150,22 @@ public SpongeItemStackGenerator build() {
}

@Override
public ItemStackGenerator.Builder from(ItemStackGenerator value) {
public ItemStackGenerator.Builder from(final ItemStackGenerator value) {
this.reset();
checkNotNull(value, "ItemStackGenerator cannot be null!");
Objects.requireNonNull(value, "ItemStackGenerator cannot be null!");
checkArgument(value instanceof SpongeItemStackGenerator, "Cannot use from on a non-Sponge implemented ItemStackGenerator!");
SpongeItemStackGenerator generator = (SpongeItemStackGenerator) value;
for (BiConsumer<ItemStack.Builder, Random> consumer : generator.biConsumers) {
this.consumers.add(consumer);
}
this.baseItem = generator.baseType;
final SpongeItemStackGenerator generator = (SpongeItemStackGenerator) value;
this.consumers.addAll(generator.biConsumers);
this.baseItem = new WeightedTable<>();
this.baseItem.addAll(generator.baseType);
return this;
}

@Override
public org.spongepowered.common.item.generation.SpongeItemStackGenerator.Builder reset() {
this.consumers.clear();
this.baseItem = null;
this.keyValues = null;
return this;
}

Expand Down
@@ -0,0 +1,26 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
@org.checkerframework.framework.qual.DefaultQualifier(org.checkerframework.checker.nullness.qual.NonNull.class)
package org.spongepowered.common.item.generation;
Expand Up @@ -28,23 +28,20 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.common.base.Preconditions;
import net.minecraft.item.MerchantOffer;
import org.spongepowered.api.data.persistence.AbstractDataBuilder;
import org.spongepowered.api.data.persistence.DataBuilder;
import org.spongepowered.api.data.persistence.DataView;
import org.spongepowered.api.data.persistence.InvalidDataException;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
import org.spongepowered.api.item.merchant.TradeOffer;
import org.spongepowered.api.data.persistence.AbstractDataBuilder;
import org.spongepowered.common.item.util.ItemStackUtil;
import org.spongepowered.common.accessor.item.MerchantOfferAccessor;
import org.spongepowered.common.item.util.ItemStackUtil;
import org.spongepowered.common.util.Constants;
import org.spongepowered.common.util.MissingImplementationException;

import java.util.Optional;

import javax.annotation.Nullable;
import java.util.Optional;

public class SpongeTradeOfferBuilder extends AbstractDataBuilder<TradeOffer> implements TradeOffer.Builder, DataBuilder<TradeOffer> {

Expand Down Expand Up @@ -202,7 +199,6 @@ protected Optional<TradeOffer> buildContent(final DataView container) throws Inv
builder.sellingItem(buyingItem)
.maxUses(container.getInt(Constants.Item.TradeOffer.MAX_QUERY).get())
.uses(container.getInt(Constants.Item.TradeOffer.USES_QUERY).get())
.canGrantExperience(container.getBoolean(Constants.Item.TradeOffer.EXPERIENCE_QUERY).get())
.merchantExperienceGranted(container.getInt(Constants.Item.TradeOffer.EXPERIENCE_GRANTED_TO_MERCHANT_QUERY).orElse(0))
.priceGrowthMultiplier(container.getDouble(Constants.Item.TradeOffer.PRICE_GROWTH_MULTIPLIER_QUERY).orElse(0.0D))
.demandBonus(container.getInt(Constants.Item.TradeOffer.DEMAND_BONUS_QUERY).orElse(0));
Expand Down

0 comments on commit 9128b15

Please sign in to comment.