diff --git a/src/generated/resources/data/pneumaticcraft/recipes/chunkloader_upgrade.json b/src/generated/resources/data/pneumaticcraft/recipes/chunkloader_upgrade.json new file mode 100644 index 000000000..4b69f54d7 --- /dev/null +++ b/src/generated/resources/data/pneumaticcraft/recipes/chunkloader_upgrade.json @@ -0,0 +1,22 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "C": { + "item": "pneumaticcraft:printed_circuit_board" + }, + "L": { + "tag": "pneumaticcraft:upgrade_components" + }, + "E": { + "item": "minecraft:ender_eye" + } + }, + "pattern": [ + "LCL", + "ECE", + "LCL" + ], + "result": { + "item": "pneumaticcraft:chunkloader_upgrade" + } +} \ No newline at end of file diff --git a/src/main/java/me/desht/pneumaticcraft/common/entity/drone/DroneEntity.java b/src/main/java/me/desht/pneumaticcraft/common/entity/drone/DroneEntity.java index 0261cb82c..47d10480f 100644 --- a/src/main/java/me/desht/pneumaticcraft/common/entity/drone/DroneEntity.java +++ b/src/main/java/me/desht/pneumaticcraft/common/entity/drone/DroneEntity.java @@ -25,6 +25,7 @@ import me.desht.pneumaticcraft.api.drone.IPathfindHandler; import me.desht.pneumaticcraft.api.drone.ProgWidgetType; import me.desht.pneumaticcraft.api.lib.NBTKeys; +import me.desht.pneumaticcraft.api.lib.Names; import me.desht.pneumaticcraft.api.pneumatic_armor.hacking.IHackableEntity; import me.desht.pneumaticcraft.api.pressure.PressureHelper; import me.desht.pneumaticcraft.api.semiblock.SemiblockEvent; @@ -117,6 +118,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -133,6 +135,7 @@ import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.ITeleporter; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.common.world.ForgeChunkManager; import net.minecraftforge.energy.IEnergyStorage; import net.minecraftforge.entity.IEntityAdditionalSpawnData; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -241,6 +244,9 @@ public class DroneEntity extends AbstractDroneEntity implements private final Map stackEnchants = new HashMap<>(); private boolean carriedEntityAIdisabled; // true if the drone's carried entity AI was already disabled + private ChunkPos prevChunkPos = null; + private final Set loadedChunks = new HashSet<>(); + public DroneEntity(EntityType type, Level world) { super(type, world); moveControl = new DroneMovementController(this); @@ -479,6 +485,8 @@ public void tick() { if (securityUpgradeCount > 1 && getHealth() > 0F) { handleFluidDisplacement(); } + + airHandler.addAir(-PneumaticValues.DRONE_USAGE_CHUNKLOAD*getUpgrades(ModUpgrades.CHUNKLOADER.get())); } else { oldLaserExtension = laserExtension; if (getActiveProgramKey().getPath().equals("dig")) { @@ -556,6 +564,11 @@ private void onFirstTick() { setHasMinigun(getUpgrades(ModUpgrades.MINIGUN.get()) > 0); + if (getUpgrades(ModUpgrades.CHUNKLOADER.get()) > 0) { + prevChunkPos = chunkPosition(); + handleDynamicChunkloading(prevChunkPos); + } + droneItemHandler.setFakePlayerReady(); aiManager.setWidgets(progWidgets); @@ -590,6 +603,38 @@ private void handleFluidDisplacement() { } } + @Override + public void setPos(double x, double y, double z) { + super.setPos(x, y, z); + if (!level.isClientSide && prevChunkPos != null && !chunkPosition().equals(prevChunkPos)) { + prevChunkPos = chunkPosition(); + handleDynamicChunkloading(prevChunkPos); + } + } + + private void handleDynamicChunkloading(ChunkPos newPos) { + for (int cx = newPos.x - 1; cx <= newPos.x + 1; cx++) { + for (int cz = newPos.z - 1; cz <= newPos.z + 1; cz++) { + ChunkPos cp = new ChunkPos(cx, cz); + if (shouldLoadChunk(cp)) loadedChunks.add(cp); + } + } + + Iterator iter = loadedChunks.iterator(); + while (iter.hasNext()) { + ChunkPos cp = iter.next(); + boolean load = shouldLoadChunk(cp); + ForgeChunkManager.forceChunk((ServerLevel) level, Names.MOD_ID, this, cp.x, cp.z, load, true); + if (!load) { + iter.remove(); + } + } + } + + private boolean shouldLoadChunk(ChunkPos cp) { + return Math.abs(cp.x - chunkPosition().x)+Math.abs(cp.z - chunkPosition().z) < getUpgrades(ModUpgrades.CHUNKLOADER.get()); + } + @Override public boolean isDescending() { // allow drones to descend through scaffolding @@ -888,6 +933,10 @@ public void die(DamageSource damageSource) { restoreFluidBlocks(false); + if (!level.isClientSide) { + loadedChunks.forEach(cp -> ForgeChunkManager.forceChunk((ServerLevel) level, Names.MOD_ID, this, cp.x, cp.z, false, true)); + } + if (shouldDropAsItem()) { ItemStack stack = new ItemStack(getDroneItem()); writeToItemStack(stack); diff --git a/src/main/java/me/desht/pneumaticcraft/common/upgrades/UpgradesDBSetup.java b/src/main/java/me/desht/pneumaticcraft/common/upgrades/UpgradesDBSetup.java index 112307881..cb630e2c4 100644 --- a/src/main/java/me/desht/pneumaticcraft/common/upgrades/UpgradesDBSetup.java +++ b/src/main/java/me/desht/pneumaticcraft/common/upgrades/UpgradesDBSetup.java @@ -42,8 +42,9 @@ public class UpgradesDBSetup { .with(ModUpgrades.MAGNET.get(), 6) .with(ModUpgrades.ARMOR.get(), 15) .with(ModUpgrades.RANGE.get(), 16) - .with(ModUpgrades.CREATIVE.get(), 1); - + .with(ModUpgrades.CREATIVE.get(), 1) + .with(ModUpgrades.CHUNKLOADER.get(), 3); + private static final Builder BASIC_DRONE_UPGRADES = new Builder() .with(ModUpgrades.VOLUME.get(), MAX_VOLUME) .with(ModUpgrades.ITEM_LIFE.get(), 10) diff --git a/src/main/java/me/desht/pneumaticcraft/lib/PneumaticValues.java b/src/main/java/me/desht/pneumaticcraft/lib/PneumaticValues.java index 037df1b62..b1ed4b76d 100644 --- a/src/main/java/me/desht/pneumaticcraft/lib/PneumaticValues.java +++ b/src/main/java/me/desht/pneumaticcraft/lib/PneumaticValues.java @@ -190,6 +190,7 @@ public class PneumaticValues { public static final int DRONE_USAGE_ATTACK = 200;//per hit public static final int DRONE_USAGE_VOID = 1;//per item public static final int DRONE_USAGE_TELEPORT = 10000;//air cost to teleport + public static final int DRONE_USAGE_CHUNKLOAD = 5;//per tick per upgrade public static final float DEF_SPEED_UPGRADE_MULTIPLIER = 1.5F; public static final float DEF_SPEED_UPGRADE_USAGE_MULTIPLIER = 1.65F; diff --git a/src/main/resources/assets/pneumaticcraft/lang/en_us.json b/src/main/resources/assets/pneumaticcraft/lang/en_us.json index c2a54c9db..59ec1153a 100644 --- a/src/main/resources/assets/pneumaticcraft/lang/en_us.json +++ b/src/main/resources/assets/pneumaticcraft/lang/en_us.json @@ -395,6 +395,7 @@ "item.pneumaticcraft.charging_module" : "Charging Module", "item.pneumaticcraft.charging_upgrade" : "Charging Upgrade", "item.pneumaticcraft.chips" : "Chips", + "item.pneumaticcraft.chunkloader_upgrade" : "Chunkloader Upgrade", "item.pneumaticcraft.cod_n_chips" : "Cod n Chips", "item.pneumaticcraft.collector_drone" : "Collector Drone", "item.pneumaticcraft.compressed_iron_boots" : "Compressed Iron Boots", @@ -1431,6 +1432,7 @@ "pneumaticcraft.gui.tab.info.item.drone" : "§0Here you can insert upgrades into the Drone. Open up other tabs to see which enhancements can be done.", "pneumaticcraft.gui.tab.info.item.drone.armorUpgrade" : "§0Armor Upgrades give the drone a little protection, reducing incoming physical damage. Each upgrade is worth one point of armor (so 15 upgrades is equivalent to a full suit of Iron armor).\nNote that equipping more than 6 Armor Upgrades does carry a small movement penalty for the drone, so you need to balance protection vs. speed.", "pneumaticcraft.gui.tab.info.item.drone.creativeUpgrade" : "§0A Creative Supply Upgrade negates all air usage, and all ammunition usage if a Minigun Upgrade is installed (note that an ammo box must still be carried by the Drone).", + "pneumaticcraft.gui.tab.info.item.drone.chunkloaderUpgrade" : "§0With one Chunkloader Upgrade inserted, the Drone keeps the chunk it's in loaded. With two, the Drone loads 5 chunks, in the shape of a cross in the cardinal directions. With three, the Drone loads 9 chunks in a 3x3 area.${br}Note that this won't allow Drones to teleport to any unloaded chunk. If you want this, see 'allow_navigate_to_unloaded_chunks' in the config.", "pneumaticcraft.gui.tab.info.item.drone.inventoryUpgrade" : "§0By default the Drone can carry one stack of items. For every Inventory Upgrade inserted, the Drone gains an additional slot in its internal storage.\n\nIt will also increase the internal liquid tank by 16000mB per upgrade, and 100000RF storage per upgrade (if installed). It also increases the rate at which the Drone can transfer RF (transfer = max storage / 100).", "pneumaticcraft.gui.tab.info.item.drone.item_lifeUpgrade" : "§0With Item Life Upgrades inserted, the Drone will be able to auto-repair, at a small air cost. The more upgrades you insert, the faster the repair and the higher the air cost.", "pneumaticcraft.gui.tab.info.item.drone.magnetUpgrade" : "§0With the Magnet Upgrade inserted, the Drone will automatically pick up nearby items, if it has free inventory space. The base range is 2 blocks, increasing by 1 block per inserted upgrade.", diff --git a/src/main/resources/assets/pneumaticcraft/models/item/chunkloader_upgrade.json b/src/main/resources/assets/pneumaticcraft/models/item/chunkloader_upgrade.json new file mode 100644 index 000000000..74dc667df --- /dev/null +++ b/src/main/resources/assets/pneumaticcraft/models/item/chunkloader_upgrade.json @@ -0,0 +1,7 @@ +{ + "parent" : "item/generated", + "textures" : { + "layer0" : "pneumaticcraft:item/upgrades/upgrade_layer0", + "layer1" : "pneumaticcraft:item/upgrades/chunkloader" + } +} diff --git a/src/main/resources/assets/pneumaticcraft/patchouli_books/book/en_us/entries/base_concepts/upgrades.json b/src/main/resources/assets/pneumaticcraft/patchouli_books/book/en_us/entries/base_concepts/upgrades.json index 6da870397..64c39f658 100644 --- a/src/main/resources/assets/pneumaticcraft/patchouli_books/book/en_us/entries/base_concepts/upgrades.json +++ b/src/main/resources/assets/pneumaticcraft/patchouli_books/book/en_us/entries/base_concepts/upgrades.json @@ -219,6 +219,12 @@ "anchor": "stomp", "recipe": "pneumaticcraft:stomp_upgrade", "text": "Crafting a Stomp Upgrade" + }, + { + "type": "crafting", + "anchor": "chunkloader", + "recipe": "pneumaticcraft:chunkloader_upgrade", + "text": "Crafting a Chunkloader Upgrade" } ] } \ No newline at end of file diff --git a/src/main/resources/assets/pneumaticcraft/textures/item/upgrades/chunkloader.png b/src/main/resources/assets/pneumaticcraft/textures/item/upgrades/chunkloader.png new file mode 100644 index 000000000..9d8fbf285 Binary files /dev/null and b/src/main/resources/assets/pneumaticcraft/textures/item/upgrades/chunkloader.png differ