/* * Copyright 2015 Demigods RPG * Copyright 2015 Alexander Chauncey * Copyright 2015 Alex Bennett * * 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 com.demigodsrpg.model; import com.demigodsrpg.DGData; import com.demigodsrpg.registry.TributeRegistry; import com.demigodsrpg.util.datasection.AbstractPersistentModel; import com.demigodsrpg.util.datasection.DataSection; import com.demigodsrpg.util.misc.MapUtil2; import org.bukkit.Material; import org.bukkit.scheduler.BukkitRunnable; import java.util.*; import java.util.concurrent.TimeUnit; public class TributeModel extends AbstractPersistentModel<String> { private static final double VALUE_K = 14.286; private static double OFFSET = 1.0; private final Material material; private List<Double> tributeTimes; private int fitness; private final TributeRegistry.Category category; private double lastKnownValue; public TributeModel(Material material, DataSection conf) { this.material = material; tributeTimes = conf.getDoubleList("tribute_times"); fitness = conf.getInt("fitness"); category = DGData.TRIBUTE_R.getCategory(material); lastKnownValue = conf.getDouble("last_known_value"); } public TributeModel(Material material, int fitness) { this.material = material; tributeTimes = new ArrayList<>(); this.fitness = fitness; category = DGData.TRIBUTE_R.getCategory(material); lastKnownValue = 1.0; } public Material getMaterial() { return material; } List<Double> getTributeTimes() { long twoWeeksAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(14); List<Double> tributeTimesClone = new ArrayList<>(); tributeTimesClone.addAll(this.tributeTimes); tributeTimesClone.stream().filter(time -> time < twoWeeksAgo).forEach(this.tributeTimes::remove); return tributeTimes; } public void addTributeTime() { tributeTimes.add((double) System.currentTimeMillis()); } public int getFitness() { return fitness; } public void setFitness(int amount) { this.fitness = amount; tributeTimes.add((double) System.currentTimeMillis()); DGData.TRIBUTE_R.register(this); } public TributeRegistry.Category getCategory() { return category; } double getFrequency() { return getTributeTimes().size() / 336; } public double getLastKnownValue() { return lastKnownValue; } private void updateValue() { if (getCategory().equals(TributeRegistry.Category.WORTHLESS)) { lastKnownValue = 0.0; } else if (getCategory().equals(TributeRegistry.Category.CHEATING)) { lastKnownValue = -3000.0; } else { lastKnownValue = (getValuePercentage() / OFFSET) * VALUE_K * DGData.TRIBUTE_R.getRegistered().size(); } DGData.TRIBUTE_R.register(this); } private double getValuePercentage() { Collection<TributeModel> allInCat = DGData.TRIBUTE_R.find(getCategory()); int size = allInCat.size(); if (size < 2) { size = 2; } Map<TributeModel, Double> map = new HashMap<>(); for (TributeModel model : allInCat) { map.put(model, model.getFrequency()); } int count = 1; double rankInCategory = 1.0; for (TributeModel model : MapUtil2.sortByValue(map, false).keySet()) { if (model.equals(this)) { rankInCategory = (double) count; break; } } double fractionOfCategory = rankInCategory / size; double categoryFitness = DGData.TRIBUTE_R.getTributesForCategory(getCategory()); double fractionOfTotal = 1 - (categoryFitness / DGData.TRIBUTE_R.getTotalTributes()); return fractionOfTotal * fractionOfCategory; } @Override public Map<String, Object> serialize() { Map<String, Object> map = new HashMap<>(); map.put("tribute_times", tributeTimes); map.put("fitness", fitness); map.put("last_known_value", lastKnownValue); return map; } @Override public String getPersistentId() { return getMaterial().name(); } public static class ValueTask extends BukkitRunnable { @Override public void run() { OFFSET = 1.0; for (TributeModel model : DGData.TRIBUTE_R.getRegistered()) { OFFSET += model.getValuePercentage(); } for (TributeModel model : DGData.TRIBUTE_R.getRegistered()) { // Trim the tribute times if (model.tributeTimes.size() > 300) { model.tributeTimes = model.tributeTimes.subList(model.tributeTimes.size() - 31, model.tributeTimes.size() - 1); } // Update the value model.updateValue(); } } } }