package com.hypixel.hytale.builtin.adventure.reputation; import com.hypixel.hytale.assetstore.AssetRegistry; import com.hypixel.hytale.assetstore.map.DefaultAssetMap; import com.hypixel.hytale.builtin.adventure.reputation.assets.ReputationGroup; import com.hypixel.hytale.builtin.adventure.reputation.assets.ReputationRank; import com.hypixel.hytale.builtin.adventure.reputation.choices.ReputationRequirement; import com.hypixel.hytale.builtin.adventure.reputation.command.ReputationCommand; import com.hypixel.hytale.builtin.adventure.reputation.store.ReputationDataResource; import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.ComponentType; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.ResourceType; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.math.util.MathUtil; import com.hypixel.hytale.server.core.asset.HytaleAssetStore; import com.hypixel.hytale.server.core.asset.type.attitude.Attitude; import com.hypixel.hytale.server.core.asset.type.gameplay.GameplayConfig; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData; import com.hypixel.hytale.server.core.entity.entities.player.pages.choices.ChoiceRequirement; import com.hypixel.hytale.server.core.plugin.JavaPlugin; import com.hypixel.hytale.server.core.plugin.JavaPluginInit; import com.hypixel.hytale.server.core.universe.world.World; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.Comparator; import java.util.List; import java.util.logging.Level; import javax.annotation.Nonnull; import javax.annotation.Nullable; public class ReputationPlugin extends JavaPlugin { private static ReputationPlugin instance; private ComponentType reputationGroupComponentType; private ResourceType reputationDataResourceType; private List reputationRanks; private int maxReputationValue = Integer.MIN_VALUE; private int minReputationValue = Integer.MAX_VALUE; public static final int NO_REPUTATION_GROUP = Integer.MIN_VALUE; public static ReputationPlugin get() { return instance; } public ReputationPlugin(@Nonnull JavaPluginInit init) { super(init); } public ComponentType getReputationGroupComponentType() { return this.reputationGroupComponentType; } @Override protected void setup() { instance = this; AssetRegistry.register( ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(ReputationRank.class, new DefaultAssetMap()) .setPath("NPC/Reputation/Ranks")) .setCodec(ReputationRank.CODEC)) .setKeyFunction(ReputationRank::getId)) .build() ); AssetRegistry.register( ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(ReputationGroup.class, new DefaultAssetMap()) .setPath("NPC/Reputation/Groups")) .setCodec(ReputationGroup.CODEC)) .setKeyFunction(ReputationGroup::getId)) .build() ); this.getCommandRegistry().registerCommand(new ReputationCommand()); ChoiceRequirement.CODEC.register("Reputation", ReputationRequirement.class, ReputationRequirement.CODEC); this.reputationDataResourceType = this.getEntityStoreRegistry() .registerResource(ReputationDataResource.class, "ReputationData", ReputationDataResource.CODEC); this.reputationGroupComponentType = this.getEntityStoreRegistry().registerComponent(ReputationGroupComponent.class, () -> { throw new UnsupportedOperationException("Not implemented!"); }); GameplayConfig.PLUGIN_CODEC.register(ReputationGameplayConfig.class, "Reputation", ReputationGameplayConfig.CODEC); } @Override protected void start() { this.reputationRanks = new ObjectArrayList(ReputationRank.getAssetMap().getAssetMap().values()); if (this.reputationRanks.size() > 1) { this.reputationRanks.sort(Comparator.comparingInt(ReputationRank::getMinValue)); int previousMaxValue = this.reputationRanks.getFirst().getMaxValue(); for (int i = 1; i < this.reputationRanks.size(); i++) { ReputationRank reputationRank = this.reputationRanks.get(i); if (previousMaxValue < reputationRank.getMinValue()) { this.getLogger() .at(Level.WARNING) .log( "There is a gap between the values of the ReputationRank %s and %s, please review the assets.", reputationRank.getId(), this.reputationRanks.get(i - 1).getId() ); } if (previousMaxValue > reputationRank.getMinValue()) { this.getLogger() .at(Level.WARNING) .log( "Min value of rank %s is already contained in rank %s, please review the asset.", reputationRank.getId(), this.reputationRanks.get(i - 1).getId() ); } previousMaxValue = reputationRank.getMaxValue(); } this.minReputationValue = this.reputationRanks.getFirst().getMinValue(); this.maxReputationValue = this.reputationRanks.getLast().getMaxValue(); } } public int changeReputation(@Nonnull Player player, @Nonnull Ref npcRef, int value, @Nonnull ComponentAccessor componentAccessor) { ReputationGroupComponent reputationGroupComponent = componentAccessor.getComponent(npcRef, this.reputationGroupComponentType); return reputationGroupComponent == null ? Integer.MIN_VALUE : this.changeReputation(player, reputationGroupComponent.getReputationGroupId(), value, componentAccessor); } public int changeReputation(@Nonnull Player player, @Nonnull String reputationGroupId, int value, @Nonnull ComponentAccessor componentAccessor) { World world = componentAccessor.getExternalData().getWorld(); ReputationGameplayConfig reputationGameplayConfig = ReputationGameplayConfig.getOrDefault(world.getGameplayConfig()); if (reputationGameplayConfig.getReputationStorageType() == ReputationGameplayConfig.ReputationStorageType.PerPlayer) { ReputationGroup reputationGroup = ReputationGroup.getAssetMap().getAsset(reputationGroupId); if (reputationGroup == null) { return Integer.MIN_VALUE; } else { PlayerConfigData playerConfigData = player.getPlayerConfigData(); Object2IntOpenHashMap reputationData = new Object2IntOpenHashMap(playerConfigData.getReputationData()); int newReputationValue = this.computeReputation(reputationData, reputationGroup, value); playerConfigData.setReputationData(reputationData); return newReputationValue; } } else { return this.changeReputation(world, reputationGroupId, value); } } public int changeReputation(@Nonnull World world, @Nonnull String reputationGroupId, int value) { ReputationGameplayConfig reputationGameplayConfig = ReputationGameplayConfig.getOrDefault(world.getGameplayConfig()); if (reputationGameplayConfig.getReputationStorageType() != ReputationGameplayConfig.ReputationStorageType.PerWorld) { return -1; } else { ReputationGroup reputationGroup = ReputationGroup.getAssetMap().getAsset(reputationGroupId); if (reputationGroup == null) { return Integer.MIN_VALUE; } else { ReputationDataResource reputationDataResource = world.getEntityStore().getStore().getResource(this.reputationDataResourceType); return this.computeReputation(reputationDataResource.getReputationStats(), reputationGroup, value); } } } private int computeReputation(@Nonnull Object2IntMap reputationData, @Nonnull ReputationGroup reputationGroup, int value) { return (Integer)reputationData.compute(reputationGroup.getId(), (k, oldValue) -> { int newValue = oldValue == null ? reputationGroup.getInitialReputationValue() + value : oldValue + value; return MathUtil.clamp(newValue, this.minReputationValue, this.maxReputationValue - 1); }); } public int getReputationValue(@Nonnull Store store, @Nonnull Ref playerEntityRef, @Nonnull Ref npcEntityRef) { ReputationGroupComponent reputationGroupComponent = store.getComponent(npcEntityRef, this.reputationGroupComponentType); return reputationGroupComponent == null ? Integer.MIN_VALUE : this.getReputationValue(store, playerEntityRef, reputationGroupComponent.getReputationGroupId()); } public int getReputationValue(@Nonnull Store store, @Nonnull Ref playerEntityRef, @Nonnull String reputationGroupId) { World world = store.getExternalData().getWorld(); Player playerComponent = store.getComponent(playerEntityRef, Player.getComponentType()); ReputationGameplayConfig reputationGameplayConfig = ReputationGameplayConfig.getOrDefault(world.getGameplayConfig()); if (reputationGameplayConfig.getReputationStorageType() == ReputationGameplayConfig.ReputationStorageType.PerPlayer) { ReputationGroup reputationGroup = ReputationGroup.getAssetMap().getAsset(reputationGroupId); if (reputationGroup != null) { Object2IntMap reputationData = playerComponent.getPlayerConfigData().getReputationData(); return this.getReputationValueForGroup(reputationData, reputationGroup); } else { return Integer.MIN_VALUE; } } else { return this.getReputationValue(store, reputationGroupId); } } public int getReputationValue(@Nonnull Store store, @Nonnull Ref npcRef) { String reputationGroupId = store.getComponent(npcRef, this.reputationGroupComponentType).getReputationGroupId(); return this.getReputationValue(store, reputationGroupId); } public int getReputationValue(@Nonnull Store store, String reputationGroupId) { World world = store.getExternalData().getWorld(); ReputationGameplayConfig reputationGameplayConfig = ReputationGameplayConfig.getOrDefault(world.getGameplayConfig()); if (reputationGameplayConfig.getReputationStorageType() != ReputationGameplayConfig.ReputationStorageType.PerWorld) { return Integer.MIN_VALUE; } else { ReputationGroup reputationGroup = ReputationGroup.getAssetMap().getAsset(reputationGroupId); if (reputationGroup == null) { return Integer.MIN_VALUE; } else { Object2IntMap reputationData = world.getEntityStore().getStore().getResource(this.reputationDataResourceType).getReputationStats(); return this.getReputationValueForGroup(reputationData, reputationGroup); } } } private int getReputationValueForGroup(@Nonnull Object2IntMap reputationData, @Nonnull ReputationGroup reputationGroup) { return reputationData.getOrDefault(reputationGroup.getId(), reputationGroup.getInitialReputationValue()); } @Nullable public ReputationRank getReputationRank(@Nonnull Store store, @Nonnull Ref ref, @Nonnull Ref npcRef) { ReputationGroupComponent reputationGroupComponent = store.getComponent(npcRef, this.reputationGroupComponentType); if (reputationGroupComponent == null) { return null; } else { String reputationGroupId = reputationGroupComponent.getReputationGroupId(); return this.getReputationRank(store, ref, reputationGroupId); } } @Nullable public ReputationRank getReputationRank(@Nonnull Store store, @Nonnull Ref ref, @Nonnull String reputationGroupId) { int value = this.getReputationValue(store, ref, reputationGroupId); return this.getReputationRankFromValue(value); } @Nullable public ReputationRank getReputationRankFromValue(int value) { if (value == Integer.MIN_VALUE) { return null; } else { for (int i = 0; i < this.reputationRanks.size(); i++) { if (this.reputationRanks.get(i).containsValue(value)) { return this.reputationRanks.get(i); } } return null; } } @Nullable public ReputationRank getReputationRank(@Nonnull Store store, @Nonnull Ref npcRef) { World world = store.getExternalData().getWorld(); ReputationGameplayConfig reputationGameplayConfig = ReputationGameplayConfig.getOrDefault(world.getGameplayConfig()); if (reputationGameplayConfig.getReputationStorageType() != ReputationGameplayConfig.ReputationStorageType.PerWorld) { return null; } else { int value = this.getReputationValue(store, npcRef); return this.getReputationRankFromValue(value); } } @Nullable public Attitude getAttitude(@Nonnull Store store, @Nonnull Ref ref, @Nonnull Ref npc) { ReputationRank reputationRank = this.getReputationRank(store, ref, npc); return reputationRank != null ? reputationRank.getAttitude() : null; } @Nullable public Attitude getAttitude(@Nonnull Store store, @Nonnull Ref npcRef) { ReputationRank reputationRank = this.getReputationRank(store, npcRef); return reputationRank != null ? reputationRank.getAttitude() : null; } }