From cd21673245f950b1662a1bf84ef28e34dfa2bde4 Mon Sep 17 00:00:00 2001 From: okx-code Date: Sun, 31 May 2026 02:53:11 +0100 Subject: [PATCH] improve ott + add seismic scanner/oil mechanics --- PrivateConfig | 2 +- .../plugins/ViaVersion/config.yml | 2 +- .../plugins/FactoryMod/config.yml | 528 +++++++++++++++++- .../plugins/ViaVersion/config.yml | 2 +- .../paper-config/plugins/Zorweth/config.yml | 9 + .../pvp-config/plugins/ViaVersion/config.yml | 2 +- .../plugins/ViaVersion/config.yml | 2 +- .../zorweth-config/plugins/Zorweth/config.yml | 7 + docker-compose.private.yml | 1 + docker-compose.yml | 4 + .../net/civmc/civproxy/QueueListener.java | 2 +- .../igotyou/FactoryMod/ConfigParser.java | 52 +- .../factories/FurnCraftChestFactory.java | 4 +- .../FurnCraftChestInteractionManager.java | 2 +- .../FactoryMod/recipes/ExtractOilRecipe.java | 65 +++ .../igotyou/FactoryMod/recipes/IRecipe.java | 7 + .../FactoryMod/recipes/InputRecipe.java | 8 +- .../FactoryMod/recipes/ProductionRecipe.java | 5 + .../recipes/space/BuildRocketRecipe.java | 12 +- .../space/CheckResearchProgressRecipe.java | 111 ++++ .../recipes/space/ResearchRecipe.java | 96 ++++ .../FactoryMod/utility/FactoryModGUI.java | 2 +- .../FactoryMod/utility/ItemUseGUI.java | 2 +- .../configs/OneTimeTeleportConfig.java | 6 + .../hacks/NewfriendAssist.java | 2 +- .../hacks/OneTimeTeleport.java | 13 +- .../CrossServerOttArrivalListener.java | 2 +- .../zorweth/DestinationTransferListener.java | 3 +- .../net/civmc/zorweth/RocketTransferKeys.java | 4 +- .../java/net/civmc/zorweth/ZorwethPlugin.java | 42 ++ .../civmc/zorweth/flight/FlightComputer.java | 3 +- .../zorweth/flight/FlightComputerGui.java | 29 +- .../net/civmc/zorweth/mechanics/Fuel.java | 47 ++ .../civmc/zorweth/mechanics/OilMechanics.java | 114 ++++ .../net/civmc/zorweth/mechanics/OilVein.java | 5 + .../zorweth/mechanics/OxygenManager.java | 5 + .../zorweth/mechanics/SeismicScanner.java | 50 ++ .../mechanics/SeismicScannerListener.java | 60 ++ .../zorweth/research/ResearchManager.java | 84 +++ .../zorweth/research/ResearchProgress.java | 4 + .../src/main/resources/config.yml | 9 + 41 files changed, 1359 insertions(+), 50 deletions(-) create mode 100644 plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ExtractOilRecipe.java create mode 100644 plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/CheckResearchProgressRecipe.java create mode 100644 plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/ResearchRecipe.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/Fuel.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilMechanics.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilVein.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OxygenManager.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScanner.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScannerListener.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchManager.java create mode 100644 plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchProgress.java diff --git a/PrivateConfig b/PrivateConfig index 7b1a91f7e..9d49d402f 160000 --- a/PrivateConfig +++ b/PrivateConfig @@ -1 +1 @@ -Subproject commit 7b1a91f7e590cd2af053d6785206598559d41c07 +Subproject commit 9d49d402f3e76c5c637293677f76a503d088268d diff --git a/ansible/files/gamma-config/plugins/ViaVersion/config.yml b/ansible/files/gamma-config/plugins/ViaVersion/config.yml index 6197325de..0eb9d08d1 100644 --- a/ansible/files/gamma-config/plugins/ViaVersion/config.yml +++ b/ansible/files/gamma-config/plugins/ViaVersion/config.yml @@ -15,7 +15,7 @@ send-supported-versions: false # Easier to configure alternative to 'block-protocols'. Uses readable version strings with possible '<' and '>' prefixes. # An example to block 1.16.4, everything below 1.16, as well as everything above 1.17.1 would be: ["<1.16", "1.16.4", ">1.17.1"] # You can use both this and the block-protocols option at the same time as well. -block-versions: ["<1.20.5"] +block-versions: ["<1.21.2"] # Block specific Minecraft protocol version numbers. # List of all Minecraft protocol versions: https://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com block-protocols: [] diff --git a/ansible/files/paper-config/plugins/FactoryMod/config.yml b/ansible/files/paper-config/plugins/FactoryMod/config.yml index 691f24d38..810219667 100644 --- a/ansible/files/paper-config/plugins/FactoryMod/config.yml +++ b/ansible/files/paper-config/plugins/FactoryMod/config.yml @@ -16,6 +16,98 @@ log_inventories: true force_include_default: true can_upgrade: true factories: + space_chem: + type: FCC + name: Space Chemistry Factory + citadelBreakReduction: 1.0 + setupcost: + glass_bottle: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GLASS_BOTTLE + amount: 512 + ink_sac: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: INK_SAC + amount: 16 + paper: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 128 + brewing_stands: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREWING_STAND + amount: 16 + wind_charge: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WIND_CHARGE + amount: 32 + glowstone_dust: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GLOWSTONE_DUST + amount: 128 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 32 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + recipes: + - manufacture_advanced_mechanical_components + - check_research_progress + - research_phase_1 + - research_phase_2 + - refine_crude_oil + - repair_space_chem_factory + crude: + type: FCC + name: Crude Oil Factory + citadelBreakReduction: 1.0 + setupcost: + copper_ingot: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_INGOT + amount: 128 + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 128 + iron_ingot: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: IRON_INGOT + amount: 128 + amethyst: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: AMETHYST_SHARD + amount: 128 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 64 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + recipes: + - extract_crude_oil + - repair_crude_oil_factory kinetics: type: FCC name: Kinetics Factory @@ -1349,13 +1441,53 @@ factories: name: Space Factory citadelBreakReduction: 1.0 setupcost: - daylight_sensor: + iron_block: v: 3839 ==: org.bukkit.inventory.ItemStack - type: DAYLIGHT_DETECTOR - amount: 1 + type: IRON_BLOCK + amount: 32 + rocket_fuel: + custom-key: rocket_fuel + amount: 128 + resin: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: RESIN + amount: 32 + ancient_debris: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ANCIENT_DEBRIS + amount: 8 + clay: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: RESIN + amount: 128 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 64 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + quartz: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: QUARTZ + amount: 512 + redstone: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: REDSTONE + amount: 128 recipes: - build_rocket + - repair_space_factory bastion_factory: type: FCC name: Bastion Factory @@ -1599,8 +1731,8 @@ factories: amount: 4 recipes: - wordbank_item - - crack_easter_egg - fabricate_netherite_upgrade + - make_sniffer_egg - fabricate_sentry_trim - fabricate_vex_trim - fabricate_wild_trim @@ -1830,11 +1962,42 @@ recipes: type: BUILD_ROCKET world: world input: - daylight_sensor: + iron_block: v: 3839 ==: org.bukkit.inventory.ItemStack - type: DAYLIGHT_DETECTOR - amount: 1 + type: IRON_BLOCK + amount: 64 + clay: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: CLAY + amount: 256 + ancient_debris: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ANCIENT_DEBRIS + amount: 20 + resin: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: RESIN_CLUMP + amount: 96 + advanced_mechanical_component: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COMPARATOR + amount: 32 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Advanced Mechanical Component + lore: + - Key component of rockets created in the Space Chemistry Factory + piston: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PISTON + amount: 20 facet_heliodor: production_time: 4s name: Facet Heliodor Gem @@ -11911,6 +12074,43 @@ recipes: ==: org.bukkit.inventory.ItemStack type: FLOW_ARMOR_TRIM_SMITHING_TEMPLATE amount: 32 + make_sniffer_egg: + type: PRODUCTION + name: Make Sniffer Egg + forceInclude: true + production_time: 4s + input: + ancient_debris: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ANCIENT_DEBRIS + amount: 9 + short_grass: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SHORT_GRASS + amount: 16 + fern: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: FERN + amount: 16 + armadillo_scute: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ARMADILLO_SCUTE + amount: 4 + sweet_berries: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SWEET_BERRIES + amount: 16 + output: + sniffer_egg: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: SNIFFER_EGG + amount: 1 wordbank_item: type: WORDBANK name: Generate item name @@ -17537,3 +17737,317 @@ recipes: lore: - Blocks mob spawns in a 96 block radius cylinder amount: 4 + extract_crude_oil: + fuel_consumption_intervall: 30m + name: Extract Oil + type: EXTRACT_OIL + input: + charcoal: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: CHARCOAL + amount: 48 + water_bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WATER_BUCKET + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + lore: + - Compacted Item + output: + crude_oil: + custom-key: crude_oil + amount: 16 + bucket: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BUCKET + amount: 1 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + lore: + - Compacted Item + repair_crude_oil_factory: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + copper_ingot: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_INGOT + amount: 16 + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 16 + iron_ingot: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: IRON_INGOT + amount: 16 + amethyst: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: AMETHYST_SHARD + amount: 16 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 8 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + health_gained: 10000 + repair_space_factory: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + iron_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: IRON_BLOCK + amount: 4 + rocket_fuel: + custom-key: rocket_fuel + amount: 16 + resin: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: RESIN + amount: 4 + ancient_debris: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ANCIENT_DEBRIS + amount: 1 + clay: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: RESIN + amount: 16 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 8 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + quartz: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: QUARTZ + amount: 64 + redstone: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: REDSTONE + amount: 16 + health_gained: 10000 + repair_space_chem_factory: + production_time: 4s + name: Repair Factory + type: REPAIR + input: + glass_bottle: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GLASS_BOTTLE + amount: 64 + ink_sac: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: INK_SAC + amount: 2 + paper: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 16 + brewing_stands: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: BREWING_STAND + amount: 2 + wind_charge: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: WIND_CHARGE + amount: 4 + glowstone_dust: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GLOWSTONE_DUST + amount: 16 + essence: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: ENDER_EYE + amount: 4 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Player Essence + lore: + - Activity reward used to fuel pearls + health_gained: 10000 + refine_crude_oil: + production_time: 4s + name: Refine Crude Oil + type: PRODUCTION + input: + crude_oil: + custom-key: crude_oil + amount: 64 + glowstone_dust: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GLOWSTONE_DUST + amount: 64 + output: + rocket_fuel: + custom-key: rocket_fuel + amount: 32 + manufacture_advanced_mechanical_components: + production_time: 4s + name: Manufacture Advanced Mechanical Components + type: PRODUCTION + input: + copper_block: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COPPER_BLOCK + amount: 256 + quartz: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: QUARTZ + amount: 256 + redstone: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: REDSTONE + amount: 512 + comparator: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COMPARATOR + amount: 32 + output: + advanced_mechanical_component: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: COMPARATOR + amount: 8 + meta: + meta-type: UNSPECIFIC + ==: ItemMeta + display-name: Advanced Mechanical Component + lore: + - Key component of rockets created in the Space Chemistry Factory + check_research_progress: + production_time: 1s + name: Check Research Progress + type: CHECK_RESEARCH_PROGRESS + input: + stick: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: STICK + amount: 1 + research_phase_1: + production_time: 64s + fuel_consumption_intervall: 8s + name: Research Phase 1 + type: RESEARCH + phase: 1 + input: + emerald: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EMERALD + amount: 5 + iron: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: IRON_INGOT + amount: 2 + gold: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GOLD_INGOT + amount: 4 + diamond: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: DIAMOND + amount: 4 + amethyst: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: AMETHYST_SHARD + amount: 8 + redstone: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: REDSTONE + amount: 16 + research_phase_2: + production_time: 64s + fuel_consumption_intervall: 8s + name: Research Phase 2 + type: RESEARCH + phase: 2 + input: + emerald: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: EMERALD + amount: 5 + iron: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: IRON_INGOT + amount: 5 + gold: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: GOLD_INGOT + amount: 15 + amethyst: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: AMETHYST_SHARD + amount: 30 + redstone: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: REDSTONE + amount: 64 + paper: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: PAPER + amount: 64 + ink_sac: + v: 3839 + ==: org.bukkit.inventory.ItemStack + type: INK_SAC + amount: 4 + rocket_fuel: + custom-key: rocket_fuel + amount: 8 diff --git a/ansible/files/paper-config/plugins/ViaVersion/config.yml b/ansible/files/paper-config/plugins/ViaVersion/config.yml index 6197325de..0eb9d08d1 100644 --- a/ansible/files/paper-config/plugins/ViaVersion/config.yml +++ b/ansible/files/paper-config/plugins/ViaVersion/config.yml @@ -15,7 +15,7 @@ send-supported-versions: false # Easier to configure alternative to 'block-protocols'. Uses readable version strings with possible '<' and '>' prefixes. # An example to block 1.16.4, everything below 1.16, as well as everything above 1.17.1 would be: ["<1.16", "1.16.4", ">1.17.1"] # You can use both this and the block-protocols option at the same time as well. -block-versions: ["<1.20.5"] +block-versions: ["<1.21.2"] # Block specific Minecraft protocol version numbers. # List of all Minecraft protocol versions: https://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com block-protocols: [] diff --git a/ansible/files/paper-config/plugins/Zorweth/config.yml b/ansible/files/paper-config/plugins/Zorweth/config.yml index b3fa98f8c..8b613b4bf 100644 --- a/ansible/files/paper-config/plugins/Zorweth/config.yml +++ b/ansible/files/paper-config/plugins/Zorweth/config.yml @@ -18,3 +18,12 @@ database: connection_timeout: 10000 idle_timeout: 600000 max_lifetime: 7200000 + +mechanics: + enabled: true + world: world + +research: + enabled: true + phase-one-runs: 100 + phase-two-runs: 200 diff --git a/ansible/files/pvp-config/plugins/ViaVersion/config.yml b/ansible/files/pvp-config/plugins/ViaVersion/config.yml index 6197325de..0eb9d08d1 100644 --- a/ansible/files/pvp-config/plugins/ViaVersion/config.yml +++ b/ansible/files/pvp-config/plugins/ViaVersion/config.yml @@ -15,7 +15,7 @@ send-supported-versions: false # Easier to configure alternative to 'block-protocols'. Uses readable version strings with possible '<' and '>' prefixes. # An example to block 1.16.4, everything below 1.16, as well as everything above 1.17.1 would be: ["<1.16", "1.16.4", ">1.17.1"] # You can use both this and the block-protocols option at the same time as well. -block-versions: ["<1.20.5"] +block-versions: ["<1.21.2"] # Block specific Minecraft protocol version numbers. # List of all Minecraft protocol versions: https://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com block-protocols: [] diff --git a/ansible/files/zorweth-config/plugins/ViaVersion/config.yml b/ansible/files/zorweth-config/plugins/ViaVersion/config.yml index 6197325de..0eb9d08d1 100644 --- a/ansible/files/zorweth-config/plugins/ViaVersion/config.yml +++ b/ansible/files/zorweth-config/plugins/ViaVersion/config.yml @@ -15,7 +15,7 @@ send-supported-versions: false # Easier to configure alternative to 'block-protocols'. Uses readable version strings with possible '<' and '>' prefixes. # An example to block 1.16.4, everything below 1.16, as well as everything above 1.17.1 would be: ["<1.16", "1.16.4", ">1.17.1"] # You can use both this and the block-protocols option at the same time as well. -block-versions: ["<1.20.5"] +block-versions: ["<1.21.2"] # Block specific Minecraft protocol version numbers. # List of all Minecraft protocol versions: https://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com block-protocols: [] diff --git a/ansible/files/zorweth-config/plugins/Zorweth/config.yml b/ansible/files/zorweth-config/plugins/Zorweth/config.yml index 43e85bc8f..d78c4c4de 100644 --- a/ansible/files/zorweth-config/plugins/Zorweth/config.yml +++ b/ansible/files/zorweth-config/plugins/Zorweth/config.yml @@ -18,3 +18,10 @@ database: connection_timeout: 10000 idle_timeout: 600000 max_lifetime: 7200000 + +mechanics: + enabled: true + world: world + +research: + enabled: false diff --git a/docker-compose.private.yml b/docker-compose.private.yml index 30eae5420..1500a5dc7 100644 --- a/docker-compose.private.yml +++ b/docker-compose.private.yml @@ -40,6 +40,7 @@ services: - ./PrivateConfig/paper/config/EvenMoreFish/config.yml:/privateconfig/plugins/EvenMoreFish/config.yml - ./PrivateConfig/paper/config/RandomSpawn/worlds.yml:/privateconfig/plugins/RandomSpawn/worlds.yml - ./PrivateConfig/paper/config/Heliodor/config.yml:/privateconfig/plugins/Heliodor/config.yml + - ./PrivateConfig/paper/config/Zorweth/mechanics.yml:/privateconfig/plugins/Zorweth/mechanics.yml gamma: environment: diff --git a/docker-compose.yml b/docker-compose.yml index cd3c6104a..d48658aab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,6 +55,10 @@ services: - ./containers/data/proxy:/server - ./ansible/files/proxy-config:/config - ./ansible/build/proxy-plugins:/plugins + deploy: + resources: + limits: + cpus: '2' paper: image: itzg/minecraft-server:stable-java25 diff --git a/plugins/civproxy-velocity/src/main/java/net/civmc/civproxy/QueueListener.java b/plugins/civproxy-velocity/src/main/java/net/civmc/civproxy/QueueListener.java index fc04efdd5..4de577b8b 100644 --- a/plugins/civproxy-velocity/src/main/java/net/civmc/civproxy/QueueListener.java +++ b/plugins/civproxy-velocity/src/main/java/net/civmc/civproxy/QueueListener.java @@ -143,7 +143,7 @@ public class QueueListener { return; } event.setCancelled(true); - event.getPlayer().sendMessage(Component.text("You cannot queue for that server unless your rocket route allows it.", NamedTextColor.RED)); + event.getPlayer().sendMessage(Component.text("You are not eligible to join that server at this time.", NamedTextColor.RED)); } private void onPreQueueConnect(final PreConnectEvent event) { diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java index 59c1260a9..26e069104 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/ConfigParser.java @@ -10,6 +10,7 @@ import com.github.igotyou.FactoryMod.recipes.CompactingRecipe; import com.github.igotyou.FactoryMod.recipes.DecompactingRecipe; import com.github.igotyou.FactoryMod.recipes.DeterministicEnchantingRecipe; import com.github.igotyou.FactoryMod.recipes.DummyParsingRecipe; +import com.github.igotyou.FactoryMod.recipes.ExtractOilRecipe; import com.github.igotyou.FactoryMod.recipes.FactoryMaterialReturnRecipe; import com.github.igotyou.FactoryMod.recipes.IRecipe; import com.github.igotyou.FactoryMod.recipes.InputRecipe; @@ -31,6 +32,8 @@ import com.github.igotyou.FactoryMod.recipes.heliodor.HeliodorFinishRecipe; import com.github.igotyou.FactoryMod.recipes.heliodor.HeliodorRefillRecipe; import com.github.igotyou.FactoryMod.recipes.scaling.ProductionRecipeModifier; import com.github.igotyou.FactoryMod.recipes.space.BuildRocketRecipe; +import com.github.igotyou.FactoryMod.recipes.space.CheckResearchProgressRecipe; +import com.github.igotyou.FactoryMod.recipes.space.ResearchRecipe; import com.github.igotyou.FactoryMod.recipes.upgrade.CharcoalConsumptionUpgradeRecipe; import com.github.igotyou.FactoryMod.recipes.upgrade.SpeedUpgradeRecipe; import com.github.igotyou.FactoryMod.structures.BlockFurnaceStructure; @@ -522,22 +525,22 @@ public class ConfigParser { identifier = name; } } + String type = config.getString("type", (parentRecipe != null) ? parentRecipe.getTypeIdentifier() : null); + if (type == null) { + plugin.warning("No type specified for recipe at " + config.getCurrentPath() + ". Skipping the recipe."); + return null; + } String prodTime = config.getString("production_time"); - if (prodTime == null && parentRecipe == null) { + if (prodTime == null && parentRecipe == null && !"EXTRACT_OIL".equals(type)) { plugin.warning("No production time specied for recipe " + name + ". Skipping it"); return null; } int productionTime; if (parentRecipe == null) { - productionTime = parseTimeAsTicks(prodTime); + productionTime = "EXTRACT_OIL".equals(type) && prodTime == null ? 0 : parseTimeAsTicks(prodTime); } else { productionTime = parentRecipe.getProductionTime(); } - String type = config.getString("type", (parentRecipe != null) ? parentRecipe.getTypeIdentifier() : null); - if (type == null) { - plugin.warning("No type specified for recipe at " + config.getCurrentPath() + ". Skipping the recipe."); - return null; - } // Force This Recipe to Show Up Even on Existing Factories (idempotently, ish) boolean forceAddExisting = config.getBoolean("forceInclude", forceIncludeAll); if (forceAddExisting) { @@ -579,6 +582,29 @@ public class ConfigParser { } result = new ProductionRecipe(identifier, name, productionTime, input, output, recipeRepresentation, modi); break; + case "EXTRACT_OIL": + ConfigurationSection oilOutputSection = config.getConfigurationSection("output"); + ItemMap oilOutput; + ItemStack oilRecipeRepresentation; + if (oilOutputSection == null) { + if (!(parentRecipe instanceof ProductionRecipe)) { + oilOutput = new ItemMap(); + oilRecipeRepresentation = null; + } else { + oilOutput = ((ProductionRecipe) parentRecipe).getOutput(); + oilRecipeRepresentation = ((ProductionRecipe) parentRecipe).getRecipeRepresentation(); + } + } else { + oilOutput = ConfigHelper.parseItemMap(oilOutputSection); + oilRecipeRepresentation = parseFirstItem(oilOutputSection); + } + ProductionRecipeModifier oilModi = parseProductionRecipeModifier(config.getConfigurationSection("modi")); + if (oilModi == null && parentRecipe instanceof ProductionRecipe + && ((ProductionRecipe) parentRecipe).getModifier() != null) { + oilModi = ((ProductionRecipe) parentRecipe).getModifier().clone(); + } + result = new ExtractOilRecipe(identifier, name, productionTime, input, oilOutput, oilRecipeRepresentation, oilModi); + break; case "COMPACT": String compactedLore = config.getString("compact_lore", (parentRecipe instanceof CompactingRecipe) ? ((CompactingRecipe) parentRecipe).getCompactedLore() @@ -961,6 +987,18 @@ public class ConfigParser { case "BUILD_ROCKET": result = new BuildRocketRecipe(identifier, name, productionTime, input, config.getString("world")); break; + case "RESEARCH": + int researchPhase = config.getInt("phase", 0); + if (researchPhase != 1 && researchPhase != 2) { + plugin.warning("Invalid research phase for recipe " + name + ". Expected 1 or 2. Skipping it"); + result = null; + break; + } + result = new ResearchRecipe(identifier, name, productionTime, input, researchPhase); + break; + case "CHECK_RESEARCH_PROGRESS": + result = new CheckResearchProgressRecipe(identifier, name, productionTime, input); + break; default: plugin.severe("Could not identify type " + config.getString("type") + " as a valid recipe identifier"); result = null; diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java index 59488c106..8b4e5566b 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/factories/FurnCraftChestFactory.java @@ -386,7 +386,7 @@ public class FurnCraftChestFactory extends Factory implements IIOFInventoryProvi if (currentRecipe instanceof InputRecipe) { int consumptionIntervall = ((InputRecipe) currentRecipe).getFuelConsumptionIntervall() > 0 ? ((InputRecipe) currentRecipe) .getFuelConsumptionIntervall() : pm.getPowerConsumptionIntervall(); - if (((FurnacePowerManager) pm).getFuelAmountAvailable() < (currentRecipe.getProductionTime() / consumptionIntervall)) { + if (((FurnacePowerManager) pm).getFuelAmountAvailable() < (currentRecipe.getProductionTime(this) / consumptionIntervall)) { p.sendMessage(ChatColor.RED + "You don't have enough fuel, the factory will run out of it before completing"); } @@ -493,7 +493,7 @@ public class FurnCraftChestFactory extends Factory implements IIOFInventoryProvi if (hasInputMaterials()) { // if the factory has been working for less than the required // time for the recipe - if (currentProductionTimer < currentRecipe.getProductionTime()) { + if (currentProductionTimer < currentRecipe.getProductionTime(this)) { int consumptionIntervall; if (currentRecipe instanceof InputRecipe) { consumptionIntervall = ((InputRecipe) currentRecipe).getFuelConsumptionIntervall() > 0 diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java index f9b033fb4..8e22cab7c 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/interactionManager/FurnCraftChestInteractionManager.java @@ -177,7 +177,7 @@ public class FurnCraftChestInteractionManager implements IInteractionManager { ChatColor.GOLD + fccf.getName() + " currently turned " + (fccf.isActive() ? "on" : "off")); if (fccf.isActive()) { p.sendMessage(ChatColor.GOLD - + String.valueOf((fccf.getCurrentRecipe().getProductionTime() - fccf.getRunningTime()) / 20) + + String.valueOf((fccf.getCurrentRecipe().getProductionTime(fccf) - fccf.getRunningTime()) / 20) + " seconds remaining until current run is complete"); } p.sendMessage(ChatColor.GOLD + "Currently selected recipe: " + fccf.getCurrentRecipe().getName()); diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ExtractOilRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ExtractOilRecipe.java new file mode 100644 index 000000000..53ecb1a12 --- /dev/null +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ExtractOilRecipe.java @@ -0,0 +1,65 @@ +package com.github.igotyou.FactoryMod.recipes; + +import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; +import com.github.igotyou.FactoryMod.recipes.scaling.ProductionRecipeModifier; +import java.util.ArrayList; +import java.util.List; +import net.civmc.zorweth.ZorwethPlugin; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.java.JavaPlugin; +import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; + +public class ExtractOilRecipe extends ProductionRecipe { + + public ExtractOilRecipe( + String identifier, + String name, + int productionTime, + ItemMap inputs, + ItemMap output, + ItemStack recipeRepresentation, + ProductionRecipeModifier modifier + ) { + super(identifier, name, productionTime, inputs, output, recipeRepresentation, modifier); + } + + @Override + public int getProductionTime(FurnCraftChestFactory fccf) { + if (!Bukkit.getPluginManager().isPluginEnabled("Zorweth")) { + return getProductionTime(); + } + return JavaPlugin.getPlugin(ZorwethPlugin.class).recordOilExtraction(fccf.getMultiBlockStructure().getCenter()) * 20; + } + + @Override + public ItemStack getRecipeRepresentation() { + ItemStack res = getRecipeRepresentationType(); + ItemMeta im = res.getItemMeta(); + im.setDisplayName(ChatColor.DARK_GREEN + getName()); + List lore = new ArrayList<>(); + lore.add(ChatColor.GOLD + "Input:"); + for (String s : getTextualInputRepresentation(null, null)) { + lore.add(ChatColor.GRAY + " - " + ChatColor.AQUA + s); + } + lore.add(""); + lore.add(ChatColor.GOLD + "Output:"); + for (String s : getTextualOutputRepresentation(null, null)) { + lore.add(ChatColor.GRAY + " - " + ChatColor.AQUA + s); + } + lore.add(""); + lore.add(ChatColor.DARK_AQUA + "Requires crude oil deposit nearby."); + lore.add(ChatColor.DARK_AQUA + "Duration is variable based on yield."); + lore.add(ChatColor.DARK_AQUA + "Multiple factories near a deposit will split the yield."); + im.setLore(lore); + res.setItemMeta(im); + return res; + } + + @Override + public String getTypeIdentifier() { + return "EXTRACT_OIL"; + } +} diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java index 8ff930ac8..6aa5ecb72 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/IRecipe.java @@ -26,6 +26,13 @@ public interface IRecipe { */ public int getProductionTime(); + /** + * @return How long this recipe takes for one run in ticks for a specific factory. + */ + default public int getProductionTime(FurnCraftChestFactory fccf) { + return getProductionTime(); + } + /** * Checks whether enough material is available in the given inventory to run * this recipe at least once diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java index 6a31f669c..f11231821 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/InputRecipe.java @@ -3,7 +3,6 @@ package com.github.igotyou.FactoryMod.recipes; import com.github.igotyou.FactoryMod.factories.Factory; import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; import com.github.igotyou.FactoryMod.utility.LoggingUtils; -import java.awt.*; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -15,7 +14,6 @@ import org.bukkit.Material; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import vg.civcraft.mc.civmodcore.chat.ChatUtils; import vg.civcraft.mc.civmodcore.inventory.CustomItem; import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; @@ -149,7 +147,7 @@ public abstract class InputRecipe implements IRecipe { * whole in an item gui */ public ItemStack getRecipeRepresentation() { - ItemStack res = new ItemStack(getRecipeRepresentationMaterial()); + ItemStack res = getRecipeRepresentationType(); ItemMeta im = res.getItemMeta(); im.setDisplayName(ChatColor.DARK_GREEN + getName()); List lore = new ArrayList<>(); @@ -172,6 +170,10 @@ public abstract class InputRecipe implements IRecipe { public abstract Material getRecipeRepresentationMaterial(); + public ItemStack getRecipeRepresentationType() { + return new ItemStack(getRecipeRepresentationMaterial()); + } + /** * Creates a list of ItemStack for a GUI representation. This list contains * all the itemstacks contained in the itemstack representation of the input diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java index 0fc793496..82c239e35 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/ProductionRecipe.java @@ -141,6 +141,11 @@ public class ProductionRecipe extends InputRecipe { return this.recipeRepresentation.getType(); } + @Override + public ItemStack getRecipeRepresentationType() { + return new ItemStack(this.recipeRepresentation); + } + public ProductionRecipeModifier getModifier() { return modifier; } diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/BuildRocketRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/BuildRocketRecipe.java index c8c179eee..a3a849af5 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/BuildRocketRecipe.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/BuildRocketRecipe.java @@ -70,7 +70,13 @@ public class BuildRocketRecipe extends InputRecipe { @Override public List getTextualOutputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { - return List.of(); + return List.of("Rocket:", + "6 uses", + "100 kg dry weight", + "50 kg per player", + "1 kg per stack", + "5,000 m/s exhaust velocity", + "Requires physical space"); } @Override @@ -80,7 +86,9 @@ public class BuildRocketRecipe extends InputRecipe { @Override public EffectFeasibility evaluateEffectFeasibility(Inventory inputInv, Inventory outputInv, FurnCraftChestFactory fccf) { - if (!fccf.getFurnace().getWorld().getName().equals(world)) { + if (!JavaPlugin.getPlugin(ZorwethPlugin.class).getResearchManager().isResearchComplete()) { + return new EffectFeasibility(false, "research is not complete"); + } else if (!fccf.getFurnace().getWorld().getName().equals(world)) { return new EffectFeasibility(false, "wrong world"); } else if (!isEmpty(fccf)) { drawRocketArea(fccf); diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/CheckResearchProgressRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/CheckResearchProgressRecipe.java new file mode 100644 index 000000000..39eaefeab --- /dev/null +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/CheckResearchProgressRecipe.java @@ -0,0 +1,111 @@ +package com.github.igotyou.FactoryMod.recipes.space; + +import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; +import com.github.igotyou.FactoryMod.recipes.EffectFeasibility; +import com.github.igotyou.FactoryMod.recipes.InputRecipe; +import java.util.List; +import java.util.UUID; +import net.civmc.zorweth.ZorwethPlugin; +import net.civmc.zorweth.research.ResearchManager; +import net.civmc.zorweth.research.ResearchProgress; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; + +public final class CheckResearchProgressRecipe extends InputRecipe { + + public CheckResearchProgressRecipe(final String identifier, final String name, final int productionTime, + final ItemMap input) { + super(identifier, name, productionTime, input); + } + + @Override + public List getInputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { + if (i == null) { + return input.getItemStackRepresentation(); + } + return createLoredStacksForInfo(i); + } + + @Override + public List getOutputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { + return List.of(); + } + + @Override + public List getTextualOutputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { + return List.of("Reports current research progress"); + } + + @Override + public Material getRecipeRepresentationMaterial() { + return Material.WRITABLE_BOOK; + } + + @Override + public EffectFeasibility evaluateEffectFeasibility(final Inventory inputInv, final Inventory outputInv, + final FurnCraftChestFactory fccf) { + final ResearchManager researchManager = getResearchManager(); + if (researchManager == null) { + return new EffectFeasibility(false, "Zorweth is not enabled"); + } + if (!researchManager.isEnabled()) { + return new EffectFeasibility(false, "research is disabled"); + } + if (!researchManager.isResearchWorld(fccf.getFurnace().getWorld())) { + return new EffectFeasibility(false, "wrong world"); + } + return new EffectFeasibility(true, null); + } + + @Override + public boolean applyEffect(final Inventory inputInv, final Inventory outputInv, final FurnCraftChestFactory fccf) { + final ResearchManager researchManager = getResearchManager(); + final World world = fccf.getFurnace().getWorld(); + if (researchManager == null || !researchManager.isEnabled() || !researchManager.isResearchWorld(world) + || !input.isContainedIn(inputInv)) { + return false; + } + if (!input.removeSafelyFrom(inputInv)) { + return false; + } + sendProgressMessage(fccf, researchManager.getResearchProgress()); + return true; + } + + @Override + public String getTypeIdentifier() { + return "CHECK_RESEARCH_PROGRESS"; + } + + private void sendProgressMessage(final FurnCraftChestFactory fccf, final ResearchProgress progress) { + final UUID activator = fccf.getActivator(); + if (activator == null) { + return; + } + final Player player = Bukkit.getPlayer(activator); + if (player == null) { + return; + } + if (progress.complete()) { + player.sendMessage(Component.text("Research is complete", NamedTextColor.GREEN)); + return; + } + player.sendMessage(Component.text("Research phase " + progress.phase() + ": " + progress.runs() + "/" + + progress.requiredRuns() + " runs complete", NamedTextColor.GREEN)); + } + + private ResearchManager getResearchManager() { + if (!Bukkit.getPluginManager().isPluginEnabled("Zorweth")) { + return null; + } + return JavaPlugin.getPlugin(ZorwethPlugin.class).getResearchManager(); + } +} diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/ResearchRecipe.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/ResearchRecipe.java new file mode 100644 index 000000000..b89574258 --- /dev/null +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/recipes/space/ResearchRecipe.java @@ -0,0 +1,96 @@ +package com.github.igotyou.FactoryMod.recipes.space; + +import com.github.igotyou.FactoryMod.factories.FurnCraftChestFactory; +import com.github.igotyou.FactoryMod.recipes.EffectFeasibility; +import com.github.igotyou.FactoryMod.recipes.InputRecipe; +import java.util.List; +import net.civmc.zorweth.ZorwethPlugin; +import net.civmc.zorweth.research.ResearchManager; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import vg.civcraft.mc.civmodcore.inventory.items.ItemMap; + +public final class ResearchRecipe extends InputRecipe { + + private final int phase; + + public ResearchRecipe(final String identifier, final String name, final int productionTime, final ItemMap input, + final int phase) { + super(identifier, name, productionTime, input); + this.phase = phase; + } + + @Override + public List getInputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { + if (i == null) { + return input.getItemStackRepresentation(); + } + return createLoredStacksForInfo(i); + } + + @Override + public List getOutputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { + return List.of(); + } + + @Override + public List getTextualOutputRepresentation(final Inventory i, final FurnCraftChestFactory fccf) { + return List.of("Advances phase " + this.phase + " research progress"); + } + + @Override + public Material getRecipeRepresentationMaterial() { + return Material.KNOWLEDGE_BOOK; + } + + @Override + public EffectFeasibility evaluateEffectFeasibility(final Inventory inputInv, final Inventory outputInv, + final FurnCraftChestFactory fccf) { + final ResearchManager researchManager = getResearchManager(); + if (researchManager == null) { + return new EffectFeasibility(false, "Zorweth is not enabled"); + } + if (!researchManager.isEnabled()) { + return new EffectFeasibility(false, "research is disabled"); + } + final World world = fccf.getFurnace().getWorld(); + if (!researchManager.isResearchWorld(world)) { + return new EffectFeasibility(false, "wrong world"); + } + if (!researchManager.canRunResearch(world, this.phase)) { + return new EffectFeasibility(false, "this research phase is not available"); + } + return new EffectFeasibility(true, null); + } + + @Override + public boolean applyEffect(final Inventory inputInv, final Inventory outputInv, final FurnCraftChestFactory fccf) { + final ResearchManager researchManager = getResearchManager(); + final World world = fccf.getFurnace().getWorld(); + if (researchManager == null || !researchManager.canRunResearch(world, this.phase) + || !input.isContainedIn(inputInv)) { + return false; + } + if (!input.removeSafelyFrom(inputInv)) { + return false; + } + researchManager.recordResearchRun(world, this.phase); + return true; + } + + @Override + public String getTypeIdentifier() { + return "RESEARCH"; + } + + private ResearchManager getResearchManager() { + if (!Bukkit.getPluginManager().isPluginEnabled("Zorweth")) { + return null; + } + return JavaPlugin.getPlugin(ZorwethPlugin.class).getResearchManager(); + } +} diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FactoryModGUI.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FactoryModGUI.java index 0e018e479..d230e6ec9 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FactoryModGUI.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/FactoryModGUI.java @@ -95,7 +95,7 @@ public class FactoryModGUI { } FurnCraftChestEgg fccEgg = (FurnCraftChestEgg) egg; InputRecipe firstRec = (InputRecipe) fccEgg.getRecipes().get(0); - ItemStack is = new ItemStack(firstRec.getRecipeRepresentationMaterial()); + ItemStack is = firstRec.getRecipeRepresentationType(); ItemUtils.setDisplayName(is, ChatColor.DARK_GREEN + fccEgg.getName()); List lore = new ArrayList<>(); lore.add(ChatColor.DARK_AQUA + "Fuel: " + ChatColor.GRAY + ItemUtils.getItemName(fccEgg.getFuel().getType())); diff --git a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/ItemUseGUI.java b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/ItemUseGUI.java index 8525df799..938dbf3a7 100644 --- a/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/ItemUseGUI.java +++ b/plugins/factorymod-paper/src/main/java/com/github/igotyou/FactoryMod/utility/ItemUseGUI.java @@ -146,7 +146,7 @@ public class ItemUseGUI { } private ItemStack getItemRecipeStack(FurnCraftChestEgg fccEgg, InputRecipe recipe, ItemStack item) { - ItemStack is = new ItemStack(recipe.getRecipeRepresentationMaterial()); + ItemStack is = recipe.getRecipeRepresentationType(); ItemUtils.setDisplayName(is, ChatColor.DARK_GREEN + fccEgg.getName()); List lore = new ArrayList<>(); lore.add(ChatColor.DARK_AQUA + recipe.getName()); diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/OneTimeTeleportConfig.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/OneTimeTeleportConfig.java index a2ca15fc7..c1a9bcf02 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/OneTimeTeleportConfig.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/configs/OneTimeTeleportConfig.java @@ -20,6 +20,7 @@ public final class OneTimeTeleportConfig extends SimpleHackConfig { private List unsafeMaterials; private long timeLimitOnUsage; private boolean limitToSameWorld; + private boolean canSend; public OneTimeTeleportConfig( final @NotNull SimpleAdminHacks plugin, @@ -60,6 +61,7 @@ public final class OneTimeTeleportConfig extends SimpleHackConfig { this.timeLimitOnUsage = ConfigHelper.parseTime(config.getString("ott_timeout", "2d")); // Parse same-world limit this.limitToSameWorld = config.getBoolean("limitToSameWorld", false); + this.canSend = config.getBoolean("canSend", true); } public @NotNull List getMaterialBlacklist() { @@ -77,4 +79,8 @@ public final class OneTimeTeleportConfig extends SimpleHackConfig { public boolean isLimitingToSameWorld() { return this.limitToSameWorld; } + + public boolean isCanSend() { + return canSend; + } } diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/NewfriendAssist.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/NewfriendAssist.java index 597ae919a..7da331a85 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/NewfriendAssist.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/NewfriendAssist.java @@ -33,7 +33,7 @@ import org.bukkit.persistence.PersistentDataType; public class NewfriendAssist extends SimpleHack implements Listener, CommandExecutor { public static final String NAME = "NewfriendAssist"; - private static final NamespacedKey ZORWETH_ROCKET_JOIN = new NamespacedKey("zorweth", "rocket_join"); + private static final NamespacedKey ZORWETH_ROCKET_JOIN = new NamespacedKey("zorweth", "no_starter_kit"); private static long newfriendCount = 0l; /** * We could use the various Bukkit methods every time we want to peak at our data, but the cost of storing it is low diff --git a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java index dfd55e080..a6f20e763 100644 --- a/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java +++ b/plugins/simpleadminhacks-paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/OneTimeTeleport.java @@ -33,6 +33,7 @@ import java.util.UUID; import java.util.logging.Level; import java.util.stream.Collectors; import net.civmc.zorweth.CrossServerOttManager; +import net.civmc.zorweth.RocketTransferKeys; import net.civmc.zorweth.ZorwethPlugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; @@ -185,7 +186,7 @@ public final class OneTimeTeleport extends SimpleHack imp case OK -> { } case FAIL_NO_OTT -> { - sender.sendMessage(Component.text("Your are no longer able to use OTT!")); + sender.sendMessage(Component.text("You are no longer able to use OTT!")); return; } case FAIL_IN_COMBAT -> { @@ -569,6 +570,13 @@ public final class OneTimeTeleport extends SimpleHack imp return null; } + private boolean isEligibleForCrossServerOtt(Player player) { + if (Bukkit.getPluginManager().isPluginEnabled("Zorweth")) { + return player.getPersistentDataContainer().has(RocketTransferKeys.NO_OTT); + } + return true; + } + private CrossServerOttManager getCrossServerOttManager() { final Plugin plugin = Bukkit.getPluginManager().getPlugin("Zorweth"); if (plugin instanceof ZorwethPlugin zorweth && plugin.isEnabled()) { @@ -882,6 +890,9 @@ public final class OneTimeTeleport extends SimpleHack imp if (!checkOTT(requestingPlayer.getUniqueId())) { return OttPermissible.FAIL_NO_OTT; } + if (!isEligibleForCrossServerOtt(requestingPlayer)) { + return OttPermissible.FAIL_NO_OTT; + } if (Bukkit.getPluginManager().isPluginEnabled("CombatTagPlus")) { final CombatTagPlus combatTagPlus = JavaPlugin.getPlugin(CombatTagPlus.class); if (combatTagPlus.getTagManager().isTagged(requestingPlayer.getUniqueId())) { diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/CrossServerOttArrivalListener.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/CrossServerOttArrivalListener.java index 8888fb12e..7c3bf2647 100644 --- a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/CrossServerOttArrivalListener.java +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/CrossServerOttArrivalListener.java @@ -55,7 +55,7 @@ public final class CrossServerOttArrivalListener implements Listener { return; } - requester.getPersistentDataContainer().set(RocketTransferKeys.OTT_JOIN, PersistentDataType.BOOLEAN, true); + requester.getPersistentDataContainer().set(RocketTransferKeys.NO_OTT, PersistentDataType.BOOLEAN, true); Bukkit.getScheduler().runTask(this.plugin, () -> completeArrival(requester.getUniqueId(), arrival)); } diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/DestinationTransferListener.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/DestinationTransferListener.java index d7cc6e383..551bf7a31 100644 --- a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/DestinationTransferListener.java +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/DestinationTransferListener.java @@ -134,7 +134,8 @@ public final class DestinationTransferListener implements Listener { return; } - player.getPersistentDataContainer().set(RocketTransferKeys.ROCKET_JOIN, PersistentDataType.BOOLEAN, true); + player.getPersistentDataContainer().set(RocketTransferKeys.NO_OTT, PersistentDataType.BOOLEAN, true); + player.getPersistentDataContainer().set(RocketTransferKeys.NO_STARTER_KIT, PersistentDataType.BOOLEAN, true); if (hasAppliedTransferMarker(player, transfer.transferId())) { markPassengerApplied(player.getUniqueId(), transfer.transferId()); diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/RocketTransferKeys.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/RocketTransferKeys.java index 422994b78..49b1261bb 100644 --- a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/RocketTransferKeys.java +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/RocketTransferKeys.java @@ -6,8 +6,8 @@ public final class RocketTransferKeys { public static final NamespacedKey SOURCE_TRANSFER_ID = new NamespacedKey("zorweth", "source_transfer_id"); public static final NamespacedKey DESTINATION_APPLIED_TRANSFER_ID = new NamespacedKey("zorweth", "destination_applied_transfer_id"); - public static final NamespacedKey ROCKET_JOIN = new NamespacedKey("zorweth", "rocket_join"); - public static final NamespacedKey OTT_JOIN = new NamespacedKey("zorweth", "ott_join"); + public static final NamespacedKey NO_STARTER_KIT = new NamespacedKey("zorweth", "no_starter_kit"); + public static final NamespacedKey NO_OTT = new NamespacedKey("zorweth", "no_ott"); public static final NamespacedKey OTT_APPLIED_ARRIVAL = new NamespacedKey("zorweth", "ott_applied_arrival"); public static final NamespacedKey PIONEER = new NamespacedKey("zorweth", "pioneer"); diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/ZorwethPlugin.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/ZorwethPlugin.java index eb067d9aa..dd4a1e4ec 100644 --- a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/ZorwethPlugin.java +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/ZorwethPlugin.java @@ -16,6 +16,9 @@ import java.util.logging.Level; import net.civmc.zorweth.database.RocketTransferDao; import net.civmc.zorweth.database.ZorwethDatabase; import net.civmc.zorweth.flight.FlightComputerGui; +import net.civmc.zorweth.mechanics.OilMechanics; +import net.civmc.zorweth.research.ResearchManager; +import org.bukkit.Location; import org.bukkit.plugin.java.JavaPlugin; import vg.civcraft.mc.civmodcore.dao.DatabaseCredentials; @@ -26,6 +29,7 @@ public final class ZorwethPlugin extends JavaPlugin { private StasisHandler stasisHandler; private RocketTransferDao rocketTransferDao; private CrossServerOttManager crossServerOttManager; + private ResearchManager researchManager; private String serverName; private String destinationServer; private String sourceWorld; @@ -34,6 +38,13 @@ public final class ZorwethPlugin extends JavaPlugin { private long pioneerEndTimestampMillis; private int worldRadius; private double deltaVMetersPerSecond; + private boolean researchEnabled; + private int researchPhaseOneRuns; + private int researchPhaseTwoRuns; + private String mechanicsWorld; + private boolean mechanicsEnabled; + + private OilMechanics mechanics; @Override public void onEnable() { @@ -47,11 +58,24 @@ public final class ZorwethPlugin extends JavaPlugin { this.rocketClipboard = loadRocketClipboard(); this.stasisHandler = new StasisHandler(); this.crossServerOttManager = new CrossServerOttManager(this); + this.researchManager = new ResearchManager(this, this.researchEnabled, this.researchPhaseOneRuns, + this.researchPhaseTwoRuns); getServer().getPluginManager().registerEvents(this.stasisHandler, this); getServer().getPluginManager().registerEvents(new FlightComputerGui(this), this); getServer().getPluginManager().registerEvents(new DestinationTransferListener(this), this); getServer().getPluginManager().registerEvents(new CrossServerOttArrivalListener(this, this.crossServerOttManager), this); Objects.requireNonNull(getCommand("pioneer")).setExecutor(new PioneerCommand(this)); + + if (mechanicsEnabled) { + this.mechanics = new OilMechanics(this, mechanicsWorld); + } + } + + public int recordOilExtraction(final Location location) { + if (mechanics == null) { + return 0; + } + return mechanics.recordOilExtraction(location); } @Override @@ -70,6 +94,10 @@ public final class ZorwethPlugin extends JavaPlugin { return this.rocketTransferDao; } + public ResearchManager getResearchManager() { + return this.researchManager; + } + public String getServerName() { return this.serverName; } @@ -112,6 +140,20 @@ public final class ZorwethPlugin extends JavaPlugin { this.pioneerEndTimestampMillis = getConfig().getLong("pioneer-end-timestamp", 0L); this.worldRadius = getConfig().getInt("world-radius", 0); this.deltaVMetersPerSecond = getConfig().getDouble("delta-v-meters-per-second", 10_000.0); + this.researchEnabled = getConfig().getBoolean("research.enabled", true); + this.researchPhaseOneRuns = loadPositiveInt("research.phase-one-runs", 1); + this.researchPhaseTwoRuns = loadPositiveInt("research.phase-two-runs", 1); + this.mechanicsEnabled = getConfig().getBoolean("mechanics.enabled", false); + this.mechanicsWorld = getConfig().getString("mechanics.world"); + } + + private int loadPositiveInt(final String path, final int defaultValue) { + final int value = getConfig().getInt(path, defaultValue); + if (value < 1) { + getLogger().warning(path + " must be at least 1, using " + defaultValue); + return defaultValue; + } + return value; } private boolean initDatabase() { diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputer.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputer.java index 4136b7707..a670b4bac 100644 --- a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputer.java +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputer.java @@ -1,6 +1,7 @@ package net.civmc.zorweth.flight; import com.sk89q.worldedit.math.BlockVector3; +import net.civmc.zorweth.mechanics.Fuel; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.Block; @@ -37,7 +38,7 @@ public class FlightComputer { } public static boolean isFuel(final ItemStack item) { - return item != null && item.getType() == Material.CHARCOAL; + return Fuel.isRocketFuel(item); } public static boolean isSittingWithGSit(final Player player) { diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputerGui.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputerGui.java index ed12a55e4..e5d16b0d5 100644 --- a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputerGui.java +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/flight/FlightComputerGui.java @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import net.civmc.zorweth.ZorwethPlugin; +import net.civmc.zorweth.mechanics.Fuel; import static net.civmc.zorweth.flight.FlightComputer.ROCKET_COMPUTER_KEY; import static net.civmc.zorweth.flight.LaunchHandler.SITTING_PLAYER_MASS_KG; import net.civmc.zorweth.transfer.RocketManifest; @@ -207,14 +208,14 @@ public final class FlightComputerGui implements Listener { } private IClickable createAddFuelButton(final Block computer) { - final ItemStack item = new ItemStack(Material.CHARCOAL); + final ItemStack item = Fuel.createRocketFuel(); item.editMeta(meta -> { meta.displayName(Component.text("Add Fuel", NamedTextColor.GREEN) .decoration(TextDecoration.ITALIC, false)); meta.lore(List.of( - Component.text("Adds charcoal from your hand.", NamedTextColor.GRAY) + Component.text("Adds rocket fuel from your hand.", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), - Component.text("1 charcoal = 4 kg fuel.", NamedTextColor.GRAY) + Component.text("1 rocket fuel = 4 kg fuel.", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false) )); }); @@ -263,7 +264,7 @@ public final class FlightComputerGui implements Listener { Component.text("and start main engine throttle.", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), Component.text("Fuel consumption: " + roundUpTenths(calculateFuelConsumptionKg(payload.fuelKg(), fuelStatus)) + " kg (" - + calculateFuelConsumptionItems(payload.fuelKg(), fuelStatus) + " charcoal)", NamedTextColor.GRAY) + + calculateFuelConsumptionItems(payload.fuelKg(), fuelStatus) + " rocket fuel)", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false) )); }); @@ -360,7 +361,7 @@ public final class FlightComputerGui implements Listener { Component.text("Passengers: " + manifest.passengers().size(), NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), Component.text("Fuel consumption: " + roundUpTenths(calculateFuelConsumptionKg(manifest.fuelKg(), fuelStatus)) + " kg (" - + calculateFuelConsumptionItems(manifest.fuelKg(), fuelStatus) + " charcoal)", NamedTextColor.GRAY) + + calculateFuelConsumptionItems(manifest.fuelKg(), fuelStatus) + " rocket fuel)", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), Component.text("Once engines have been started, there is no going back.", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false) @@ -398,9 +399,9 @@ public final class FlightComputerGui implements Listener { meta.displayName(Component.text("Fuel Status", enoughFuel ? NamedTextColor.GREEN : NamedTextColor.RED) .decoration(TextDecoration.ITALIC, false)); meta.lore(List.of( - Component.text("Fuel: " + roundUpTenths(status.currentFuelKg()) + " kg (" + status.fuelItems() + " charcoal)", NamedTextColor.GRAY) + Component.text("Fuel: " + roundUpTenths(status.currentFuelKg()) + " kg (" + status.fuelItems() + " rocket fuel)", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), - Component.text("Required: " + roundUpTenths(status.requiredFuelKg()) + " kg (" + status.requiredFuelItems() + " charcoal)", NamedTextColor.GRAY) + Component.text("Required: " + roundUpTenths(status.requiredFuelKg()) + " kg (" + status.requiredFuelItems() + " rocket fuel)", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), Component.text("Cargo mass: " + roundUpTenths(status.cargoMassKg()) + " kg", NamedTextColor.GRAY) .decoration(TextDecoration.ITALIC, false), @@ -414,14 +415,14 @@ public final class FlightComputerGui implements Listener { private void addFuel(final Player player, final Block computer) { final ItemStack hand = player.getInventory().getItemInMainHand(); if (!FlightComputer.isFuel(hand)) { - player.sendMessage(Component.text("Hold charcoal in your main hand to add fuel.", NamedTextColor.RED)); + player.sendMessage(Component.text("Hold rocket fuel in your main hand to add fuel.", NamedTextColor.RED)); return; } final int amount = hand.getAmount(); FlightComputer.setFuelKg(computer, FlightComputer.getFuelKg(computer) + (amount * LaunchHandler.FUEL_ITEM_MASS_KG)); player.getInventory().setItemInMainHand(null); - player.sendMessage(Component.text("Added " + amount + " charcoal to the rocket.", NamedTextColor.GREEN)); + player.sendMessage(Component.text("Added " + amount + " rocket fuel to the rocket.", NamedTextColor.GREEN)); } private void siphonFuel(final Player player, final Block computer) { @@ -434,11 +435,11 @@ public final class FlightComputerGui implements Listener { final ItemStack hand = player.getInventory().getItemInMainHand(); final int space; if (hand.getType().isAir()) { - space = Material.CHARCOAL.getMaxStackSize(); + space = Fuel.createRocketFuel().getMaxStackSize(); } else if (FlightComputer.isFuel(hand)) { space = hand.getMaxStackSize() - hand.getAmount(); } else { - player.sendMessage(Component.text("Empty your main hand or hold charcoal to siphon fuel.", NamedTextColor.RED)); + player.sendMessage(Component.text("Empty your main hand or hold rocket fuel to siphon fuel.", NamedTextColor.RED)); return; } if (space <= 0) { @@ -448,12 +449,14 @@ public final class FlightComputerGui implements Listener { final int removed = Math.min((int) (stored / LaunchHandler.FUEL_ITEM_MASS_KG), space); if (hand.getType().isAir()) { - player.getInventory().setItemInMainHand(new ItemStack(Material.CHARCOAL, removed)); + final ItemStack fuel = Fuel.createRocketFuel(); + fuel.setAmount(removed); + player.getInventory().setItemInMainHand(fuel); } else { hand.setAmount(hand.getAmount() + removed); } FlightComputer.setFuelKg(computer, stored - (removed * LaunchHandler.FUEL_ITEM_MASS_KG)); - player.sendMessage(Component.text("Siphoned " + removed + " charcoal from the rocket.", NamedTextColor.GREEN)); + player.sendMessage(Component.text("Siphoned " + removed + " rocket fuel from the rocket.", NamedTextColor.GREEN)); } diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/Fuel.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/Fuel.java new file mode 100644 index 000000000..40a8dbaa4 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/Fuel.java @@ -0,0 +1,47 @@ +package net.civmc.zorweth.mechanics; + +import java.util.List; +import io.papermc.paper.datacomponent.DataComponentTypes; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import vg.civcraft.mc.civmodcore.inventory.CustomItem; + +public class Fuel { + + public static ItemStack createCrudeOil() { + ItemStack item = new ItemStack(Material.RECOVERY_COMPASS); + item.setData(DataComponentTypes.ITEM_MODEL, new NamespacedKey("minecraft", "charcoal")); + ItemMeta meta = item.getItemMeta(); + meta.itemName(Component.text("Crude Oil", TextColor.color(64, 52, 40))); + meta.lore(List.of(Component.text("It smells pretty noxious.", NamedTextColor.WHITE), + Component.text("Can be refined to rocket fuel.", NamedTextColor.WHITE))); + meta.setEnchantmentGlintOverride(true); + item.setItemMeta(meta); + CustomItem.registerCustomItem("crude_oil", item); + + return item; + } + + public static ItemStack createRocketFuel() { + ItemStack item = new ItemStack(Material.RECOVERY_COMPASS); + item.setData(DataComponentTypes.ITEM_MODEL, new NamespacedKey("minecraft", "resin_brick")); + ItemMeta meta = item.getItemMeta(); + meta.itemName(Component.text("Rocket Fuel", TextColor.color(162, 113, 52))); + meta.lore(List.of(Component.text("Used to refuel rockets.", NamedTextColor.WHITE), + Component.text("Each item represents 4 kg of fuel.", NamedTextColor.WHITE))); + meta.setEnchantmentGlintOverride(true); + item.setItemMeta(meta); + CustomItem.registerCustomItem("rocket_fuel", item); + + return item; + } + + public static boolean isRocketFuel(final ItemStack item) { + return CustomItem.isCustomItem(item, "rocket_fuel"); + } +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilMechanics.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilMechanics.java new file mode 100644 index 000000000..0308a7495 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilMechanics.java @@ -0,0 +1,114 @@ +package net.civmc.zorweth.mechanics; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import net.civmc.zorweth.ZorwethPlugin; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.CraftingRecipe; +import vg.civcraft.mc.civmodcore.config.ConfigHelper; + +public class OilMechanics { + + private final String world; + private final List oilPos; + private final int radius; + private final long activeExtractorWindowMillis; + private final Map> activeExtractors; + + public OilMechanics(ZorwethPlugin plugin, String mechanicsWorld) { + YamlConfiguration mechanics = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), "mechanics.yml")); + + List oilPos = new ArrayList<>(); + List> positions = mechanics.getMapList("oil"); + for (Map position : positions) { + oilPos.add(new OilVein((int) position.get("x"), (int) position.get("z"), (int) position.get("yield"))); + } + + this.oilPos = oilPos; + this.world = mechanicsWorld; + this.radius = mechanics.getInt("radius"); + this.activeExtractorWindowMillis = ConfigHelper.parseTime(mechanics.getString("active-extractor-window", "30s")); + this.activeExtractors = new HashMap<>(); + + CraftingRecipe recipe = SeismicScanner.getRecipe(plugin); + Bukkit.addRecipe(recipe); + plugin.getServer().getPluginManager().registerEvents(new SeismicScannerListener(recipe, this), plugin); + + Fuel.createCrudeOil(); + Fuel.createRocketFuel(); + } + + public int recordOilExtraction(final Location location) { + OilVein vein = findOilVein(location); + if (vein == null) { + return 0; + } + + long now = System.currentTimeMillis(); + Map extractors = activeExtractors.computeIfAbsent(vein, ignored -> new HashMap<>()); + pruneExpiredExtractors(extractors, now); + extractors.put(location.toBlockLocation(), now); + return vein.yield() * extractors.size(); + } + + private OilVein findOilVein(final Location location) { + if (!world.equals(location.getWorld().getName())) { + return null; + } + + OilVein richestVein = null; + for (OilVein vein : oilPos) { + if (location.toBlockLocation().distanceSquared(new Location(location.getWorld(), vein.x(), location.getY(), vein.z())) < radius * radius) { + if (richestVein == null || vein.yield() > richestVein.yield()) { + richestVein = vein; + } + } + } + return richestVein; + } + + public VeinPing ping(final Location location) { + if (!world.equals(location.getWorld().getName())) { + return null; + } + + OilVein closestVein = null; + double distance = Double.MAX_VALUE; + + for (OilVein vein : oilPos) { + double veinDistance = ((vein.x() - location.blockX()) * (vein.x() - location.blockX())) + + ((vein.z() - location.blockZ()) * (vein.z() - location.blockZ())); + + if (closestVein == null || veinDistance < distance) { + closestVein = vein; + distance = veinDistance; + } + } + + if (distance < radius * radius) { + return VeinPing.VEIN; + } else if (distance < 100 * 100) { + return VeinPing.HIGH; + } else if (distance < 200 * 200) { + return VeinPing.LOW; + } else { + return null; + } + } + + public enum VeinPing { + VEIN, + HIGH, + LOW + } + + private void pruneExpiredExtractors(final Map extractors, final long now) { + extractors.entrySet().removeIf( + entry -> now - entry.getValue() > activeExtractorWindowMillis); + } +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilVein.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilVein.java new file mode 100644 index 000000000..783481045 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OilVein.java @@ -0,0 +1,5 @@ +package net.civmc.zorweth.mechanics; + +public record OilVein(int x, int z, int yield) { + +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OxygenManager.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OxygenManager.java new file mode 100644 index 000000000..cee378410 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/OxygenManager.java @@ -0,0 +1,5 @@ +package net.civmc.zorweth.mechanics; + +public class OxygenManager { + +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScanner.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScanner.java new file mode 100644 index 000000000..e9322093f --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScanner.java @@ -0,0 +1,50 @@ +package net.civmc.zorweth.mechanics; + +import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.item.UseCooldown; +import java.util.List; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.CraftingRecipe; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.recipe.CraftingBookCategory; +import org.bukkit.plugin.Plugin; +import vg.civcraft.mc.civmodcore.inventory.CustomItem; + +public class SeismicScanner { + + public static final Key COOLDOWN_GROUP = new NamespacedKey("zorweth", "seismic_scanner_cooldown"); + + public static ItemStack createSeismicScanner() { + ItemStack item = new ItemStack(Material.RECOVERY_COMPASS); + item.setData(DataComponentTypes.USE_COOLDOWN, UseCooldown.useCooldown(5).cooldownGroup(COOLDOWN_GROUP).build()); + ItemMeta meta = item.getItemMeta(); + meta.itemName(Component.text("Seismic Scanner", NamedTextColor.DARK_AQUA)); + meta.lore(List.of(Component.text("An essential tool for prospecting crude oil deposits", NamedTextColor.WHITE), + Component.text("Can detect deposits up to 200 blocks away", NamedTextColor.WHITE), + Component.text("Right click to use", NamedTextColor.WHITE))); + meta.setEnchantmentGlintOverride(true); + item.setItemMeta(meta); + CustomItem.registerCustomItem("seismic_scanner", item); + + return item; + } + + static boolean isSeismicScanner(ItemStack item) { + return CustomItem.isCustomItem(item, "seismic_scanner"); + } + + static CraftingRecipe getRecipe(Plugin plugin) { + ShapedRecipe recipe = new ShapedRecipe(new NamespacedKey(plugin, "seismic_scanner"), SeismicScanner.createSeismicScanner()) + .shape(" x ", "xox", " x ") + .setIngredient('x', Material.GOLD_INGOT) + .setIngredient('o', Material.AMETHYST_SHARD); + recipe.setCategory(CraftingBookCategory.MISC); + return recipe; + } +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScannerListener.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScannerListener.java new file mode 100644 index 000000000..0c0be5342 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/mechanics/SeismicScannerListener.java @@ -0,0 +1,60 @@ +package net.civmc.zorweth.mechanics; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.CraftingRecipe; + +public class SeismicScannerListener implements Listener { + + private final CraftingRecipe recipe; + private final OilMechanics mechanics; + + public SeismicScannerListener(CraftingRecipe recipe, OilMechanics mechanics) { + this.recipe = recipe; + this.mechanics = mechanics; + } + + @EventHandler + public void on(PlayerJoinEvent event) { + event.getPlayer().discoverRecipe(recipe.getKey()); + } + + @EventHandler + public void on(PlayerInteractEvent event) { + if (!(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK)) { + return; + } + if (!SeismicScanner.isSeismicScanner(event.getItem())) { + return; + } + Player player = event.getPlayer(); + if (player.getCooldown(SeismicScanner.COOLDOWN_GROUP) > 0) { + return; + } + + OilMechanics.VeinPing ping = mechanics.ping(player.getLocation()); + + HoverEvent hover = HoverEvent.showText(Component.text("Seismic scanners can detect crude oil in stages of: 200 blocks away, 100 blocks away, and on an oil deposit")); + + player.setCooldown(SeismicScanner.COOLDOWN_GROUP, 20 * 5); + + if (ping == null) { + player.sendMessage(Component.text("You don't seem to be able to detect any seismic anomalies nearby.", NamedTextColor.GRAY, TextDecoration.ITALIC).hoverEvent(hover)); + } else if (ping == OilMechanics.VeinPing.LOW) { + player.sendMessage(Component.text("Seismic activity seems to be slightly higher than usual nearby.", NamedTextColor.YELLOW, TextDecoration.ITALIC).hoverEvent(hover)); + } else if (ping == OilMechanics.VeinPing.HIGH) { + player.sendMessage(Component.text("There are strong indications that oil can be found nearby.", TextColor.color(224, 198, 41), TextDecoration.ITALIC).hoverEvent(hover)); + } else if (ping == OilMechanics.VeinPing.VEIN) { + player.sendMessage(Component.text("This spot seems ideal for oil extraction.", NamedTextColor.GOLD, TextDecoration.ITALIC).hoverEvent(hover)); + } + } +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchManager.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchManager.java new file mode 100644 index 000000000..60335acd1 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchManager.java @@ -0,0 +1,84 @@ +package net.civmc.zorweth.research; + +import java.util.Objects; +import net.civmc.zorweth.ZorwethPlugin; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public final class ResearchManager { + + private static final NamespacedKey PHASE_ONE_RUNS_KEY = new NamespacedKey("zorweth", "research_phase_one_runs"); + private static final NamespacedKey PHASE_TWO_RUNS_KEY = new NamespacedKey("zorweth", "research_phase_two_runs"); + + private final ZorwethPlugin plugin; + private final boolean enabled; + private final int phaseOneRequiredRuns; + private final int phaseTwoRequiredRuns; + + public ResearchManager(final ZorwethPlugin plugin, final boolean enabled, final int phaseOneRequiredRuns, + final int phaseTwoRequiredRuns) { + this.plugin = Objects.requireNonNull(plugin); + this.enabled = enabled; + this.phaseOneRequiredRuns = phaseOneRequiredRuns; + this.phaseTwoRequiredRuns = phaseTwoRequiredRuns; + } + + public boolean isEnabled() { + return this.enabled; + } + + public boolean isResearchWorld(final World world) { + return world != null && world.getName().equals(this.plugin.getSourceWorld()); + } + + public boolean canRunResearch(final World world, final int phase) { + if (!this.enabled || !isResearchWorld(world)) { + return false; + } + final PersistentDataContainer data = world.getPersistentDataContainer(); + final int phaseOneCompleted = getRuns(data, PHASE_ONE_RUNS_KEY); + final int phaseTwoCompleted = getRuns(data, PHASE_TWO_RUNS_KEY); + return switch (phase) { + case 1 -> phaseOneCompleted < this.phaseOneRequiredRuns; + case 2 -> phaseOneCompleted >= this.phaseOneRequiredRuns && phaseTwoCompleted < this.phaseTwoRequiredRuns; + default -> false; + }; + } + + public boolean isResearchComplete() { + return !this.enabled || getResearchProgress().complete(); + } + + public void recordResearchRun(final World world, final int phase) { + if (!canRunResearch(world, phase)) { + return; + } + final PersistentDataContainer data = world.getPersistentDataContainer(); + final NamespacedKey key = phase == 1 ? PHASE_ONE_RUNS_KEY : PHASE_TWO_RUNS_KEY; + data.set(key, PersistentDataType.INTEGER, getRuns(data, key) + 1); + } + + public ResearchProgress getResearchProgress() { + final World world = Bukkit.getWorld(this.plugin.getSourceWorld()); + if (world == null) { + return new ResearchProgress(1, 0, this.phaseOneRequiredRuns, false); + } + final PersistentDataContainer data = world.getPersistentDataContainer(); + final int phaseOneCompleted = getRuns(data, PHASE_ONE_RUNS_KEY); + if (phaseOneCompleted < this.phaseOneRequiredRuns) { + return new ResearchProgress(1, phaseOneCompleted, this.phaseOneRequiredRuns, false); + } + final int phaseTwoCompleted = getRuns(data, PHASE_TWO_RUNS_KEY); + if (phaseTwoCompleted < this.phaseTwoRequiredRuns) { + return new ResearchProgress(2, phaseTwoCompleted, this.phaseTwoRequiredRuns, false); + } + return new ResearchProgress(2, this.phaseTwoRequiredRuns, this.phaseTwoRequiredRuns, true); + } + + private int getRuns(final PersistentDataContainer data, final NamespacedKey key) { + return Math.max(0, data.getOrDefault(key, PersistentDataType.INTEGER, 0)); + } +} diff --git a/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchProgress.java b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchProgress.java new file mode 100644 index 000000000..304f87833 --- /dev/null +++ b/plugins/zorweth-paper/src/main/java/net/civmc/zorweth/research/ResearchProgress.java @@ -0,0 +1,4 @@ +package net.civmc.zorweth.research; + +public record ResearchProgress(int phase, int runs, int requiredRuns, boolean complete) { +} diff --git a/plugins/zorweth-paper/src/main/resources/config.yml b/plugins/zorweth-paper/src/main/resources/config.yml index 9f30e9bad..73367ff54 100644 --- a/plugins/zorweth-paper/src/main/resources/config.yml +++ b/plugins/zorweth-paper/src/main/resources/config.yml @@ -8,6 +8,11 @@ pioneer-end-timestamp: 0 world-radius: 10000 delta-v-meters-per-second: 10000 +research: + enabled: false + phase-one-runs: 100 + phase-two-runs: 200 + database: ==: vg.civcraft.mc.civmodcore.dao.DatabaseCredentials user: root @@ -25,3 +30,7 @@ flight_computer_reinforcement: ==: org.bukkit.inventory.ItemStack v: 3839 type: DIAMOND + +mechanics: + enabled: false + world: world