Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<denareconomy.version>0.2.4</denareconomy.version>
<rpcharacters.version>2.0.1</rpcharacters.version>
<tlibs.version>2.0.0</tlibs.version>
<vehicleframework.version>2.7.0</vehicleframework.version>
<vehicleframework.version>2.8.0</vehicleframework.version>
<vfbuilders.version>2.1.0</vfbuilders.version>
</properties>

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/tfminecraft/simplefactions/Cache.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ public static boolean requireProvinces(org.bukkit.command.CommandSender sender)
public static double infrastructureStation = 10;
public static double infrastructurePort = 10;
public static double infrastructureAirport = 5;
public static double infrastructureTrack = 10;
public static int infrastructureTrackRefreshSeconds = 300;

public static Map<Scope, LawEffect> baseEffects = new HashMap<>();

Expand Down
33 changes: 33 additions & 0 deletions src/main/java/net/tfminecraft/simplefactions/SimpleFactions.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;

import net.tfminecraft.simplefactions.Cache;
import net.tfminecraft.simplefactions.map.ProvinceGrid;
import net.tfminecraft.simplefactions.map.infra.TrackProvinceCache;
import net.tfminecraft.simplefactions.map.presence.ProvincePresenceListener;
import net.tfminecraft.simplefactions.map.presence.ProvincePresenceService;
import net.tfminecraft.simplefactions.map.presence.ProvincePresenceTickService;
Expand Down Expand Up @@ -169,6 +171,7 @@ public class SimpleFactions extends JavaPlugin{
new net.tfminecraft.simplefactions.mercenary.contract.AttendanceService.Hook();
private ProvinceManager provinceSnapshot = new ProvinceManager();
private ProvinceGrid provinceGrid;
private BukkitTask trackInfrastructureRefreshTask;
private final PlayerVehicleRegistry vehicleRegistry = new PlayerVehicleRegistry();
private VehicleRegistryPersistence vehicleRegistryPersistence;
private final InstallationVehicleOwnerSync installationVehicleOwnerSync =
Expand Down Expand Up @@ -345,15 +348,20 @@ public void onEnable() {
sessionManager.start();
if (Cache.provincesEnabled) {
provinceSnapshot = provinceManager.createSnapshotShell();
refreshTrackProvinces(() -> {});
provinceManager.recalculate();
// Hub tax is assessed at the day change; do it once now so menus are right before then.
net.tfminecraft.simplefactions.guild.hub.HubTaxService.refresh(provinceManager);
long refreshTicks = Cache.infrastructureTrackRefreshSeconds * 20L;
trackInfrastructureRefreshTask = getServer().getScheduler().runTaskTimer(
this, () -> { refreshTrackProvinces(); }, refreshTicks, refreshTicks);
}
inventoryManager.start();
vehicleMaintenanceDecayTask.start();
}
@Override
public void onDisable() {
if (trackInfrastructureRefreshTask != null) trackInfrastructureRefreshTask.cancel();
net.tfminecraft.simplefactions.integration.rpcharacters.chat.RpCharactersChatIntegration.unregister();
MercenaryStatService.clearAll();
net.tfminecraft.simplefactions.mercenary.company.MercenaryEligibility.reset();
Expand Down Expand Up @@ -518,6 +526,31 @@ public ProvinceGrid getProvinceGrid() {
return provinceGrid;
}

public boolean refreshTrackProvinces() {
return refreshTrackProvinces(provinceManager::recalculate);
}

private boolean refreshTrackProvinces(Runnable recalculate) {
return TrackProvinceCache.live().refresh(() -> {
if (provinceGrid == null) {
return java.util.Set.of();
}
if (!getServer().getPluginManager().isPluginEnabled("VehicleFramework")) {
TrackProvinceCache.live().vehicleFrameworkUnavailable(
message -> getLogger().info("[SimpleFactions] " + message));
return java.util.Set.of();
}
java.util.Map<Integer, net.tfminecraft.simplefactions.map.provinces.Province> provinces =
new java.util.HashMap<>();
for (net.tfminecraft.simplefactions.map.provinces.Province province : provinceManager.getProvinces()) {
provinces.put(province.getId(), province);
}
return net.tfminecraft.simplefactions.guild.hub.VehicleFrameworkTrackProvinces.sample(
Cache.worldName, provinceGrid, provinces);
}, recalculate,
message -> getLogger().warning("[SimpleFactions] " + message));
}

public SessionManager getSessionManager() {
return sessionManager;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.tfminecraft.simplefactions.guild.hub;

import java.util.List;
import java.util.Map;
import java.util.Set;

import net.tfminecraft.simplefactions.map.ProvinceGrid;
import net.tfminecraft.simplefactions.map.infra.TrackProvinceLookup;
import net.tfminecraft.simplefactions.map.infra.TrackProvinceLookup.Point;
import net.tfminecraft.simplefactions.map.provinces.Province;
import net.tfminecraft.vehicleframework.VehicleFramework;
import net.tfminecraft.vehicleframework.tracks.TrackRegistry;
import net.tfminecraft.vehicleframework.tracks.TrackSamplePoint;

/** The only track sampler here that names VehicleFramework's sample point type. */
public final class VehicleFrameworkTrackProvinces {
private VehicleFrameworkTrackProvinces() {}

public static Set<Integer> sample(String world, ProvinceGrid grid, Map<Integer, Province> provinces) {
TrackRegistry tracks = VehicleFramework.getTrackRegistry();
if (tracks == null || world == null) return Set.of();
List<TrackSamplePoint> samples = tracks.sampleTrack(world, 8);
return TrackProvinceLookup.collect(grid, samples.stream()
.map(point -> new Point(point.x(), point.y(), point.z())).toList(), provinces);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ public void loadConfig(File configFile) {
Cache.infrastructureStation = config.getDouble("infrastructure.station", 10);
Cache.infrastructurePort = config.getDouble("infrastructure.port", 10);
Cache.infrastructureAirport = config.getDouble("infrastructure.airport", 5);
Cache.infrastructureTrack = config.getDouble("infrastructure.track", 10);
Cache.infrastructureTrackRefreshSeconds = Math.max(30,
config.getInt("infrastructure.track-refresh-seconds", 300));

Cache.settlementLargePopulationThreshold = config.getInt("settlement-large-population-threshold", 8);
Cache.portSeaProximityBlocks = config.getInt("port-sea-proximity-blocks", 20);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,8 @@ public void time() {
// and settle the day on trade that reflects them.
runDailyStep("supply hub links", () -> {
net.tfminecraft.simplefactions.guild.hub.HubNetwork.forgetRoutes();
SimpleFactions.getInstance().getProvinceManager().recalculate();
boolean tracksChanged = SimpleFactions.getInstance().refreshTrackProvinces();
if (!tracksChanged) SimpleFactions.getInstance().getProvinceManager().recalculate();
net.tfminecraft.simplefactions.guild.hub.HubTaxService.refresh(
SimpleFactions.getInstance().getProvinceManager());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ private void recalculateInfrastructure() {
province.getTradeCarry(), !province.isSea(), origin, province.getNeighbours()));
}
Map<Integer, Double> sources = InfrastructureSources.collect(
provinces, FactionManager.getAllGuilds(), FactionManager.getCopy());
provinces, FactionManager.getAllGuilds(), FactionManager.getCopy(),
net.tfminecraft.simplefactions.map.infra.TrackProvinceCache.live().provinces());
Map<Integer, InfrastructureSpread.Arrival> infrastructure = InfrastructureSpread.spread(
graph, sources, Cache.infrastructureWildernessSpread, Cache.infrastructureSpreadFloor);
for (Province province : provinces.values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import net.tfminecraft.simplefactions.Cache;
import net.tfminecraft.simplefactions.enums.GuildModifier;
Expand All @@ -16,7 +17,8 @@ public final class InfrastructureSources {
private InfrastructureSources() {}

public static Map<Integer, Double> collect(
Map<Integer, Province> provinces, Collection<Guild> guilds, Collection<Faction> factions) {
Map<Integer, Province> provinces, Collection<Guild> guilds, Collection<Faction> factions,
Set<Integer> trackProvinces) {
Map<Integer, Double> sources = new HashMap<>();
for (Guild guild : guilds) {
if (guild == null || !guild.isBase() || !guild.hasCapital()) continue;
Expand All @@ -34,6 +36,9 @@ public static Map<Integer, Double> collect(
add(provinces, sources, installation.getProvince(), amount);
}
}
for (Integer id : trackProvinces) {
add(provinces, sources, id, Cache.infrastructureTrack);
}
return sources;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package net.tfminecraft.simplefactions.map.infra;

import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;

/** Immutable track source snapshot shared by live and preview recalculations. */
public final class TrackProvinceCache {
private static final TrackProvinceCache LIVE = new TrackProvinceCache();

private volatile Set<Integer> provinces = Set.of();
private boolean warned;
private boolean vehicleFrameworkUnavailableLogged;

public static TrackProvinceCache live() {
return LIVE;
}

public Set<Integer> provinces() {
return provinces;
}

public void vehicleFrameworkUnavailable(Consumer<String> info) {
if (!vehicleFrameworkUnavailableLogged) {
vehicleFrameworkUnavailableLogged = true;
info.accept("VehicleFramework is not enabled; railway track gives no infrastructure.");
}
}

public boolean refresh(Supplier<Set<Integer>> sampler, Runnable recalculate, Consumer<String> warning) {
Set<Integer> sampled;
try {
sampled = Set.copyOf(sampler.get());
} catch (RuntimeException | LinkageError e) {
sampled = Set.of();
if (!warned) {
warned = true;
warning.accept("Could not read VehicleFramework tracks; track infrastructure is disabled.");
}
}
if (provinces.equals(sampled)) return false;
provinces = sampled;
recalculate.run();
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.tfminecraft.simplefactions.map.infra;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import net.tfminecraft.simplefactions.map.ProvinceGrid;
import net.tfminecraft.simplefactions.map.provinces.Province;

public final class TrackProvinceLookup {
public record Point(double x, double y, double z) {}

private TrackProvinceLookup() {}

public static Set<Integer> collect(ProvinceGrid grid, Iterable<Point> points, Map<Integer, Province> provinces) {
Set<Integer> ids = new HashSet<>();
for (Point point : points) {
int id = grid.getAt((int) Math.floor(point.x()), (int) Math.floor(point.z()));
Province province = provinces.get(id);
if (id != 0 && province != null && !province.isSea()) ids.add(id);
}
return Set.copyOf(ids);
}
}
2 changes: 2 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ infrastructure:
station: 10
port: 10
airport: 5
track: 10
track-refresh-seconds: 300

terrain-modifiers:
- FARMLAND 0.95
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ void restore() {
Cache.infrastructureStation = previous[4];
Cache.infrastructurePort = previous[5];
Cache.infrastructureAirport = previous[6];
Cache.infrastructureTrack = previous[7];
Cache.infrastructureTrackRefreshSeconds = (int) previous[8];
}

@Test
Expand All @@ -42,7 +44,7 @@ void missingSectionUsesDefaultsAndResetsPreviousSettings() throws IOException {
""");
load("enable-map: false\n");

assertValues(20, 0.75, 0.25, 0.5, 10, 10, 5);
assertValues(20, 0.75, 0.25, 0.5, 10, 10, 5, 10, 300);
}

@Test
Expand All @@ -52,7 +54,7 @@ void missingKeysUseDefaultsIndependently() throws IOException {
full: 30
""");

assertValues(30, 0.75, 0.25, 0.5, 10, 10, 5);
assertValues(30, 0.75, 0.25, 0.5, 10, 10, 5, 10, 300);
}

@Test
Expand All @@ -66,9 +68,11 @@ void configuredKeysAreReadIntoCache() throws IOException {
station: 12
port: 8
airport: 4
track: 17
track-refresh-seconds: 45
""");

assertValues(30, 0.80, 0.10, 0.25, 12, 8, 4);
assertValues(30, 0.80, 0.10, 0.25, 12, 8, 4, 17, 45);
}

@Test
Expand Down Expand Up @@ -101,7 +105,8 @@ private void load(String yaml) throws IOException {
private static double[] values() {
return new double[] {Cache.infrastructureFull, Cache.infrastructureTarget,
Cache.infrastructureWildernessSpread, Cache.infrastructureSpreadFloor,
Cache.infrastructureStation, Cache.infrastructurePort, Cache.infrastructureAirport};
Cache.infrastructureStation, Cache.infrastructurePort, Cache.infrastructureAirport,
Cache.infrastructureTrack, Cache.infrastructureTrackRefreshSeconds};
}

private static void assertValues(double... expected) {
Expand Down
Loading
Loading