Merge branch '1.21' into worldgen-placement-providers

This commit is contained in:
DBotThePony 2025-03-22 00:38:45 +07:00
commit b6b3cbed81
Signed by: DBot
GPG Key ID: DCC23B5715498507
174 changed files with 1475 additions and 787 deletions

1
.gitignore vendored
View File

@ -32,3 +32,4 @@ forge*changelog.txt
shapegen_output.java
/runs
/.kotlin

View File

@ -23,7 +23,7 @@ import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider
import net.neoforged.neoforge.data.event.GatherDataEvent
import net.neoforged.neoforge.registries.NeoForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidResearchDataProvider
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDataProvider
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.math.yRotationBlockstateNorth
import ru.dbotthepony.mc.otm.core.util.WriteOnce

View File

@ -4,9 +4,9 @@ import net.minecraft.tags.ItemTags
import net.minecraft.world.item.Items
import net.neoforged.neoforge.common.Tags
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidResearchDescriptions
import ru.dbotthepony.mc.otm.android.AndroidResearchResults
import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescriptions
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResults
import ru.dbotthepony.mc.otm.player.android.AndroidResearchType
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent

View File

@ -15,8 +15,8 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.Block
import net.neoforged.neoforge.common.data.LanguageProvider
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.player.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.player.android.AndroidResearchType
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.datagen.DataGen
import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock

View File

@ -19,7 +19,7 @@ import net.minecraft.world.level.block.Block
import net.neoforged.neoforge.common.Tags
import net.neoforged.neoforge.data.event.GatherDataEvent
import net.neoforged.neoforge.registries.NeoForgeRegistries
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.datagen.DataGen
import java.util.EnumMap

View File

@ -20,7 +20,7 @@ import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.client.event.RenderPlayerEvent;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.player.IMatteryPlayer;
import javax.annotation.Nonnull;
import java.util.Set;

View File

@ -1,51 +0,0 @@
package ru.dbotthepony.mc.otm.mixin;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodData;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
@Mixin(FoodData.class)
public class FoodDataMixin {
@Shadow(remap = false)
private int lastFoodLevel;
@Shadow(remap = false)
private int tickTimer;
@Shadow(remap = false)
private int foodLevel;
@Shadow(remap = false)
private float exhaustionLevel;
@Inject(
method = "tick(Lnet/minecraft/world/entity/player/Player;)V",
at = @At("HEAD"),
remap = false,
cancellable = true
)
private void tick(Player player, CallbackInfo info) {
var it = ((IMatteryPlayer) player).getOtmPlayer();
if (it.isAndroid()) {
info.cancel();
// полностью подменяем логику если андроид
lastFoodLevel = foodLevel;
if (player.level().getDifficulty() == Difficulty.PEACEFUL) {
exhaustionLevel = 0f;
} else {
tickTimer = 0;
}
// не обновляем уровень истощения ибо он обнуляется логикой внутри MatteryPlayerCapability
// а так же не регенерируем
// ну и не получаем урон от "голодания"
}
}
}

View File

@ -0,0 +1,19 @@
package ru.dbotthepony.mc.otm.mixin;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.Level;
import net.neoforged.fml.ModList;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import ru.dbotthepony.mc.otm.core.IMatteryLevel;
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource;
@Mixin(Level.class)
public abstract class LevelMixin implements IMatteryLevel {
private final RandomSource otm_random = ModList.get().isLoaded("better_random") ? null : new GJRAND64RandomSource();
@Override
public @Nullable RandomSource getOtmRandom() {
return otm_random;
}
}

View File

@ -7,7 +7,8 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.player.IMatteryPlayer;
import ru.dbotthepony.mc.otm.core.IMatteryLevel;
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents;
@Mixin(AbstractHurtingProjectile.class)
@ -24,7 +25,7 @@ public class MixinAbstractHurtingProjectile {
AbstractHurtingProjectile proj = (AbstractHurtingProjectile)(Object)this;
if (cap.isAndroid() && proj.getOwner() != entity) {
entity.level().playSound(entity, proj.blockPosition(), MSoundEvents.INSTANCE.getANDROID_PROJ_PARRY(), SoundSource.PLAYERS, 1.0f, 0.95f + entity.level().getRandom().nextFloat() * 0.1f);
entity.level().playSound(entity, proj.blockPosition(), MSoundEvents.INSTANCE.getANDROID_PROJ_PARRY(), SoundSource.PLAYERS, 1.0f, 0.95f + ((IMatteryLevel) entity.level()).getOtmRandom().nextFloat() * 0.1f);
}
}
}

View File

@ -17,8 +17,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.capability.MatteryPlayer;
import ru.dbotthepony.mc.otm.player.IMatteryPlayer;
import ru.dbotthepony.mc.otm.player.MatteryPlayer;
import java.util.function.Predicate;

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.mixin;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.GameRules;
import net.neoforged.neoforge.event.EventHooks;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
@ -10,7 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.player.IMatteryPlayer;
import ru.dbotthepony.mc.otm.config.ServerConfig;
import ru.dbotthepony.mc.otm.core.util.ExperienceUtilsKt;
import ru.dbotthepony.mc.otm.registry.game.MItems;
@ -28,7 +29,7 @@ public class MixinLivingEntity {
at = @At("HEAD"),
cancellable = true)
public void dropExperience(@Nullable Entity killer, CallbackInfo hook) {
if (((Object) this) instanceof Player player && ServerConfig.INSTANCE.getDROP_EXPERIENCE_CAPSULES()) {
if (((Object) this) instanceof Player player && ServerConfig.INSTANCE.getDROP_EXPERIENCE_CAPSULES() && !player.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY)) {
hook.cancel();
var android = ((IMatteryPlayer) player).getOtmPlayer();

View File

@ -6,7 +6,7 @@ import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import ru.dbotthepony.mc.otm.capability.MatteryPlayer;
import ru.dbotthepony.mc.otm.player.MatteryPlayer;
@Mixin(Minecraft.class)
public class MixinMinecraft {

View File

@ -3,8 +3,8 @@ package ru.dbotthepony.mc.otm.mixin;
import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodData;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
@ -12,15 +12,17 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.capability.MatteryPlayer;
import ru.dbotthepony.mc.otm.player.IMatteryPlayer;
import ru.dbotthepony.mc.otm.player.MatteryFoodData;
import ru.dbotthepony.mc.otm.player.MatteryPlayer;
import java.util.Objects;
@Mixin(Player.class)
public class MixinPlayer implements IMatteryPlayer {
public abstract class MixinPlayer implements IMatteryPlayer {
private Player otmSelf() {
return (Player) (Object) this;
}
@ -87,4 +89,15 @@ public class MixinPlayer implements IMatteryPlayer {
private void readAdditionalSaveData(CompoundTag data, CallbackInfo ci) {
otmPlayer.deserializeNBT(data.getCompound("overdrive_that_matters_player"), otmSelf().registryAccess());
}
@Shadow
protected FoodData foodData;
@Inject(
method = "<init>",
at = @At("TAIL")
)
private void ctorMix(Level level, BlockPos pos, float yRot, GameProfile gameProfile, CallbackInfo info) {
foodData = new MatteryFoodData(otmSelf());
}
}

View File

@ -118,7 +118,7 @@ val isPaused: Boolean get() {
return isPausedImpl
}
fun recordClientThread() {
internal fun recordClientThread() {
clientThreads.add(Thread.currentThread())
}
@ -186,19 +186,19 @@ var SERVER_IS_LIVE = false
private val LOGGER = LogManager.getLogger()
fun onServerTickPre(event: ServerTickEvent.Pre) {
internal fun onServerTickPre(event: ServerTickEvent.Pre) {
preServerTick.tick()
serverThreads.add(Thread.currentThread())
}
fun onServerTickPost(event: ServerTickEvent.Post) {
internal fun onServerTickPost(event: ServerTickEvent.Post) {
postServerTick.tick()
// чтоб не плодить кучу подписчиков, вызовем напрямую отсюда
GraphNodeList.tick()
AbstractProfiledStorage.onServerPostTick()
}
fun onLevelTickPre(event: LevelTickEvent.Pre) {
internal fun onLevelTickPre(event: LevelTickEvent.Pre) {
preWorldTick[event.level]?.tick()
if (event.level.isClientSide) {
@ -208,7 +208,7 @@ fun onLevelTickPre(event: LevelTickEvent.Pre) {
}
}
fun onLevelTickPost(event: LevelTickEvent.Post) {
internal fun onLevelTickPost(event: LevelTickEvent.Post) {
postWorldTick[event.level]?.tick()
}
@ -310,7 +310,7 @@ private fun clear() {
postWorldTick.clear()
}
fun onServerStarting(event: ServerAboutToStartEvent) {
internal fun onServerStarting(event: ServerAboutToStartEvent) {
clear()
SERVER_IS_LIVE = true
_server = event.server
@ -318,13 +318,13 @@ fun onServerStarting(event: ServerAboutToStartEvent) {
serverCounter.incrementAndGet()
}
fun onServerStopping(event: ServerStoppingEvent) {
internal fun onServerStopping(event: ServerStoppingEvent) {
clear()
SERVER_IS_LIVE = false
serverCounter.incrementAndGet()
}
fun onServerStopped(event: ServerStoppedEvent) {
internal fun onServerStopped(event: ServerStoppedEvent) {
if (SERVER_IS_LIVE) {
LOGGER.fatal("ServerStoppingEvent did not fire. If server has crashed this is normal. However, if server finished it's work 'gracefully' this is a bug!")

View File

@ -6,16 +6,15 @@ import net.neoforged.bus.api.EventPriority
import net.neoforged.fml.common.Mod
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent
import ru.dbotthepony.mc.otm.android.AndroidResearchDescription
import ru.dbotthepony.mc.otm.android.AndroidResearchDescriptions
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidResearchResult
import ru.dbotthepony.mc.otm.android.AndroidResearchResults
import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescription
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescriptions
import ru.dbotthepony.mc.otm.player.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResult
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResults
import ru.dbotthepony.mc.otm.player.android.feature.EnderTeleporterFeature
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.decorative.DevChestBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.drive.DrivePool
import ru.dbotthepony.mc.otm.client.AndroidAbilityKeyMapping
import ru.dbotthepony.mc.otm.client.AndroidMenuKeyMapping
@ -44,7 +43,7 @@ import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer
import ru.dbotthepony.mc.otm.compat.curios.isCuriosLoaded
import ru.dbotthepony.mc.otm.compat.curios.onCuriosSlotModifiersUpdated
import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.config.PlayerConfig
import ru.dbotthepony.mc.otm.config.CablesConfig
import ru.dbotthepony.mc.otm.config.ClientConfig
import ru.dbotthepony.mc.otm.config.ExopackConfig
@ -158,7 +157,6 @@ object OverdriveThatMatters {
MOD_BUS.addListener(EventPriority.NORMAL, TritaniumArmorModel::register)
MOD_BUS.addListener(EventPriority.NORMAL, GravitationStabilizerModel::register)
MOD_BUS.addListener(EventPriority.NORMAL, BreadMonsterModel::register)
MOD_BUS.addListener(EventPriority.NORMAL, MCreativeTabs::register)
MOD_BUS.addListener(EventPriority.NORMAL, BatteryBankRenderer.Companion::onRegisterAdditionalModels)
MOD_BUS.addListener(EventPriority.NORMAL, MatterBatteryBankRenderer.Companion::onRegisterAdditionalModels)
@ -175,7 +173,7 @@ object OverdriveThatMatters {
ClientConfig.register(container)
ServerConfig.register(container)
CablesConfig.register(container)
AndroidConfig.register(container)
PlayerConfig.register(container)
ExopackConfig.register(container)
ItemsConfig.register(container)
MachinesConfig.register(container)

View File

@ -633,18 +633,18 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
}
}
fun onLevelUnload(event: LevelEvent.Unload) {
internal fun onLevelUnload(event: LevelEvent.Unload) {
val level = event.level as? ServerLevel ?: return
playerMap.remove(level)
tickingMap.remove(level)
}
fun onServerStopping(event: ServerStoppingEvent) {
internal fun onServerStopping(event: ServerStoppingEvent) {
playerMap.clear()
tickingMap.clear()
}
fun postLevelTick(event: LevelTickEvent.Post) {
internal fun postLevelTick(event: LevelTickEvent.Post) {
val level = event.level as? ServerLevel ?: return
tickingMap[level]?.forEach {
@ -663,14 +663,14 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
}
}
fun onWatch(event: ChunkWatchEvent.Watch) {
internal fun onWatch(event: ChunkWatchEvent.Watch) {
playerMap
.computeIfAbsent(event.level) { Long2ObjectOpenHashMap() }
.computeIfAbsent(event.pos.toLong(), Long2ObjectFunction { ChunkSubscribers(event.level, it) })
.subscribe(event.player)
}
fun onForget(event: ChunkWatchEvent.UnWatch) {
internal fun onForget(event: ChunkWatchEvent.UnWatch) {
val levelMap = playerMap[event.level] ?: return
val subs = levelMap.get(event.pos.toLong()) ?: return
@ -679,7 +679,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
}
}
fun playerDisconnected(event: PlayerEvent.PlayerLoggedOutEvent) {
internal fun playerDisconnected(event: PlayerEvent.PlayerLoggedOutEvent) {
for (tree in playerMap.values) {
tree.values.removeIf {
it.unsubscribe(event.entity as ServerPlayer)

View File

@ -44,7 +44,7 @@ import ru.dbotthepony.mc.otm.core.math.getSphericalBlockPositions
import ru.dbotthepony.mc.otm.core.math.times
import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.isClient
import ru.dbotthepony.mc.otm.matter.MatterManager
import ru.dbotthepony.mc.otm.registry.MDamageTypes
@ -271,7 +271,7 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery
}
// шанс 1% что черная дыра потеряет 0.1 MtU каждую секунду * силу гравитации дыры ^ -1
if (level.random.nextDouble() < 0.01 * 0.05 * (1 / gravitationStrength)) {
if (level.otmRandom.nextDouble() < 0.01 * 0.05 * (1 / gravitationStrength)) {
this.mass += HAWKING_MASS_LOSE_STEP
}

View File

@ -34,7 +34,7 @@ import ru.dbotthepony.mc.otm.core.math.times
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
import ru.dbotthepony.mc.otm.core.multiblock.MultiblockStatus
import ru.dbotthepony.mc.otm.core.multiblock.shapedMultiblock
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.InvalidableLazy
import ru.dbotthepony.mc.otm.menu.tech.BlackHoleGeneratorMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -86,8 +86,8 @@ class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState)
multiblock?.blockEntities(MatterHatchBlockEntity.INPUT_TAG)?.iterator()?.map { it.matter }?.toList() ?: listOf()
}
val energy = CombinedProfiledEnergyStorage(FlowDirection.NONE, energyTarget::value, { level?.random })
val matter = CombinedProfiledMatterStorage(FlowDirection.NONE, matterTarget::value, { level?.random })
val energy = CombinedProfiledEnergyStorage(FlowDirection.NONE, energyTarget::value, { level?.otmRandom })
val matter = CombinedProfiledMatterStorage(FlowDirection.NONE, matterTarget::value, { level?.otmRandom })
enum class Mode(val label: Component, val tooltip: Component) {
TARGET_MASS(TranslatableComponent("otm.gui.black_hole_generator.sustain.mode"), TranslatableComponent("otm.gui.black_hole_generator.sustain.desc")),

View File

@ -14,7 +14,7 @@ import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.collect.reduce
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.shuffle
import ru.dbotthepony.mc.otm.graph.GraphNodeList
import ru.dbotthepony.mc.otm.onceServer
@ -627,7 +627,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
}
fun receiveEnergy(howMuch: Decimal, simulate: Boolean, fromNode: EnergyCableBlockEntity.Node, fromSide: RelativeSide): Decimal {
livelyNodesList.shuffle(fromNode.blockEntity.level!!.random)
livelyNodesList.shuffle(fromNode.blockEntity.level!!.otmRandom)
val itr = livelyNodesList.iterator()
var received = Decimal.ZERO

View File

@ -32,7 +32,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
@ -71,7 +71,7 @@ class CargoCrateBlockEntity(
if (interactingPlayers++ == 0 && level != null && !isRemoved && level.getBlockState(blockPos).block is CargoCrateBlock) {
level.setBlock(blockPos, blockState.setValue(CargoCrateBlock.IS_OPEN, true), Block.UPDATE_CLIENTS)
level.playSound(null, blockPos, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level.random.nextFloat() * 0.2f)
level.playSound(null, blockPos, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level.otmRandom.nextFloat() * 0.2f)
level.gameEvent(GameEvent.CONTAINER_OPEN, blockPos, GameEvent.Context.of(blockState))
}
}

View File

@ -59,7 +59,7 @@ class DevChestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB
return cache
}
fun mappingsChanged(event: IdMappingEvent) {
internal fun mappingsChanged(event: IdMappingEvent) {
cache.clear()
}
}

View File

@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.data.codec.minRange
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
@ -106,10 +106,15 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
if (!status.job.matterValue.isZero)
status.throttleFast()
} else {
status.job.matterValue -= matter.receiveMatter(status.job.matterValue, false)
val received = matter.receiveMatter(status.job.matterValue, false)
status.job.matterValue -= received
if (status.job.matterValue.isPositive)
status.noMatter()
if (status.job.matterValue.isPositive) {
if (received.isPositive)
status.noMatter(1)
else
status.noMatter()
}
}
}
@ -126,7 +131,7 @@ class MatterDecomposerBlockEntity(pos: BlockPos, state: BlockState)
return JobContainer.success(
DecomposerJob(
(level?.random?.nextDouble() ?: 1.0) <= 0.2 * upgrades.failureMultiplier,
(level?.otmRandom?.nextDouble() ?: 1.0) <= 0.2 * upgrades.failureMultiplier,
matter.matter,
matter.complexity * MachinesConfig.MATTER_DECOMPOSER.workTimeMultiplier
)

View File

@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.UpgradeContainer
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
import ru.dbotthepony.mc.otm.matter.IMatterValue
@ -264,7 +264,7 @@ class MatterReconstructorBlockEntity(blockPos: BlockPos, blockState: BlockState)
return
}
if (failureChance * upgrades.failureMultiplier <= 0.0 || level!!.random.nextDouble() >= failureChance * upgrades.failureMultiplier)
if (failureChance * upgrades.failureMultiplier <= 0.0 || level!!.otmRandom.nextDouble() >= failureChance * upgrades.failureMultiplier)
repairProgress += progressPerTick
energy.extractEnergy(energyConsumption * (progressPerTick / thisProgressPerTick), false)

View File

@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
import ru.dbotthepony.mc.otm.item.matter.MatterDustItem
import ru.dbotthepony.mc.otm.menu.matter.MatterRecyclerMenu
@ -117,7 +117,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
stack.shrink(1)
container.setChanged(0)
val actualMatter = dustMatter.matter * (0.4 + level!!.random.nextDouble() * 0.6)
val actualMatter = dustMatter.matter * (0.4 + level!!.otmRandom.nextDouble() * 0.6)
return JobContainer.success(
RecyclerJob(

View File

@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.data.codec.minRange
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
@ -184,7 +184,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
task = allocation.task.id,
matterValue = matter.matter,
pattern = Optional.ofNullable(allocation.pattern),
asDust = (level?.random?.nextDouble() ?: 1.0) * upgrades.failureMultiplier > (allocation.pattern?.researchPercent ?: 2.0),
asDust = (level?.otmRandom?.nextDouble() ?: 1.0) * upgrades.failureMultiplier > (allocation.pattern?.researchPercent ?: 2.0),
ticks = ticks,
))
}

View File

@ -23,7 +23,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets8

View File

@ -35,7 +35,7 @@ import ru.dbotthepony.mc.otm.container.balance
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.maybe
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
import ru.dbotthepony.mc.otm.recipe.MatteryCookingRecipe
import ru.dbotthepony.mc.otm.recipe.MicrowaveRecipe
@ -153,7 +153,7 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
recipe.workTime * config.workTimeMultiplier,
config.energyConsumption * toProcess,
experience = recipe.experience.sample(level.random) * toProcess))
experience = recipe.experience.sample(level.otmRandom) * toProcess))
}
}

View File

@ -14,10 +14,10 @@ import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.ProxiedEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.shuffle
import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -58,7 +58,7 @@ class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
val ents = level.getEntitiesInEllipsoid(blockPos.center, Vec3(MachinesConfig.AndroidCharger.RADIUS_WIDTH, MachinesConfig.AndroidCharger.RADIUS_HEIGHT, MachinesConfig.AndroidCharger.RADIUS_WIDTH)) { it is Player }
ents.shuffle(level.random)
ents.shuffle(level.otmRandom)
for ((ent) in ents) {
val ply = (ent as Player).matteryPlayer

View File

@ -13,11 +13,11 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.capability.moveEnergy
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.shuffle
import ru.dbotthepony.mc.otm.core.util.countingLazy
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
@ -90,7 +90,7 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Ma
val y = blockPos.y.toDouble()
val z = blockPos.z.toDouble()
for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0)).shuffle(level.random)) {
for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0)).shuffle(level.otmRandom)) {
if (ent.matteryPlayer.isAndroid)
moveEnergy(energy, ent.matteryPlayer.androidEnergy, amount = energy.batteryLevel, simulate = false, ignoreFlowRestrictions = true)
}

View File

@ -23,7 +23,7 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.shuffle
import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -60,7 +60,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
if (!howMuch.isPositive)
return Decimal.ZERO
containerSlotIndices.shuffle(level!!.random)
containerSlotIndices.shuffle(level!!.otmRandom)
var summ = Decimal.ZERO
var remaining = howMuch

View File

@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.core.multiblock.BlockEntityTag
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockAccess
import ru.dbotthepony.mc.otm.core.multiblock.IMultiblockListener
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.InvalidableLazy
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -43,7 +43,7 @@ class EnergyInterfaceBlockEntity(
multiblocks.keys.iterator().flatMap { it.blockEntities(TARGET).iterator() }.map { it.energyInterfaceTarget }.toList()
}
val energy = CombinedProfiledEnergyStorage(FlowDirection.input(isInput), targets::value, { level?.random })
val energy = CombinedProfiledEnergyStorage(FlowDirection.input(isInput), targets::value, { level?.otmRandom })
override fun onAddedToMultiblock(multiblock: IMultiblockAccess) {
check(!isRemoved) { "Block was removed" }

View File

@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
import ru.dbotthepony.mc.otm.core.lookupOrThrow
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.countingLazy
import ru.dbotthepony.mc.otm.item.consumables.EssenceCapsuleItem
import ru.dbotthepony.mc.otm.item.EssenceServoItem
@ -173,7 +173,7 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
val diff = dmgPerExp - repairPoints.toFloat()
if (diff > 0f) {
repairPoints += if ((level?.random?.nextFloat() ?: 1f) <= diff) 1 else 0
repairPoints += if ((level?.otmRandom?.nextFloat() ?: 1f) <= diff) 1 else 0
}
experienceStored -= 1
@ -202,7 +202,7 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma
level!!.playSound(null, ent.x, ent.y, ent.z,
SoundEvents.EXPERIENCE_ORB_PICKUP, SoundSource.BLOCKS,
0.1F, 0.5F + level!!.random.nextFloat() * 0.25F
0.1F, 0.5F + level!!.otmRandom.nextFloat() * 0.25F
)
}

View File

@ -21,7 +21,7 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.balance
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.maybe
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
import ru.dbotthepony.mc.otm.registry.game.MRecipes
@ -90,7 +90,7 @@ class PlatePressBlockEntity(
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
recipe.workTime * MachinesConfig.PLATE_PRESS.workTimeMultiplier,
MachinesConfig.PLATE_PRESS.energyConsumption * toProcess,
experience = recipe.experience.sample(level.random) * toProcess))
experience = recipe.experience.sample(level.otmRandom) * toProcess))
}
override fun tick() {

View File

@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.block.MatteryBlock
import ru.dbotthepony.mc.otm.block.addSimpleDescription
import ru.dbotthepony.mc.otm.block.entity.tech.AndroidStationBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.capability
import com.google.common.collect.Streams
import net.minecraft.ChatFormatting
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.neoforged.neoforge.capabilities.Capabilities
@ -34,13 +33,11 @@ import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.util.formatFluidLevel
import ru.dbotthepony.mc.otm.player.matteryPlayer
import java.util.stream.Stream
private val LOGGER = LogManager.getLogger()
val Player.matteryPlayer: MatteryPlayer get() = (this as IMatteryPlayer).otmPlayer
val LivingEntity.matteryPlayer: MatteryPlayer? get() = (this as? IMatteryPlayer)?.otmPlayer
/**
* Does a checked energy receive, calls [IMatteryEnergyStorage.receiveEnergyChecked] if possible
*/

View File

@ -118,7 +118,7 @@ object DrivePool {
}
}
fun onWorldSave(event: LevelEvent.Save) {
internal fun onWorldSave(event: LevelEvent.Save) {
writeBacklog(event.level.server!!.registryAccess())
}

View File

@ -8,8 +8,8 @@ import net.neoforged.neoforge.client.event.RenderLevelStageEvent
import net.neoforged.neoforge.client.settings.KeyConflictContext
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidActiveFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.android.AndroidActiveFeature
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.is3DContext
@ -46,7 +46,7 @@ object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConfl
}
}
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
internal fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
if (!isDown) {
return
}
@ -73,7 +73,7 @@ object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConfl
}
}
fun onRenderLevel(event: RenderLevelStageEvent) {
internal fun onRenderLevel(event: RenderLevelStageEvent) {
if (!isDown) {
return
}
@ -92,7 +92,7 @@ object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConfl
}
}
fun register(event: RegisterKeyMappingsEvent) {
internal fun register(event: RegisterKeyMappingsEvent) {
event.register(this)
}
}

View File

@ -11,12 +11,11 @@ import net.neoforged.neoforge.client.event.RenderGuiEvent
import net.neoforged.neoforge.client.settings.KeyConflictContext
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidFeature
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.android.AndroidFeature
import ru.dbotthepony.mc.otm.player.android.AndroidSwitchableFeature
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.drawArc
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.angleDifference
import ru.dbotthepony.mc.otm.core.math.normalizeAngle
@ -95,7 +94,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
}
}
fun onMouseClick(event: InputEvent.MouseButton.Pre) {
internal fun onMouseClick(event: InputEvent.MouseButton.Pre) {
// fix binding wheel menu to mouse button not calling back setIsDown(false)
if (isDown && event.action == 0 && key.type == InputConstants.Type.MOUSE && InputConstants.Type.MOUSE.getOrCreate(event.button) == key) {
isDown = false
@ -312,7 +311,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
const val COOLDOWN_ICON_SIZE = 18f
const val COOLDOWN_ICON_MARGIN = 12f
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
internal fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
if (!grabbedInput) {
lastRender = milliTimeD
renderRegular(event)
@ -326,7 +325,7 @@ object AndroidMenuKeyMapping : KeyMapping("key.otm.android_menu", KeyConflictCon
}
}
fun register(event: RegisterKeyMappingsEvent) {
internal fun register(event: RegisterKeyMappingsEvent) {
event.register(this)
}
}

View File

@ -18,9 +18,9 @@ import net.neoforged.neoforge.client.event.ScreenEvent
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.config.ClientConfig
import ru.dbotthepony.mc.otm.android.feature.JumpBoostFeature
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.android.feature.JumpBoostFeature
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.ExopackInventoryScreen
@ -38,7 +38,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.registry.game.AndroidFeatures
import java.util.WeakHashMap
fun onMovementInputUpdate(event: MovementInputUpdateEvent) {
internal fun onMovementInputUpdate(event: MovementInputUpdateEvent) {
val ply = event.entity
val input = event.input
@ -198,7 +198,7 @@ private fun exosuitInventoryLogic(screen: Screen, addListener: (GuiEventListener
scrollbar.scroll = inventoryScroll
}
fun onMouseDragged(event: ScreenEvent.MouseDragged.Pre) {
internal fun onMouseDragged(event: ScreenEvent.MouseDragged.Pre) {
val screen = minecraft.screen as? AbstractContainerScreen<*> ?: return
if (screen is MatteryScreen<*>)
@ -214,7 +214,7 @@ fun onMouseDragged(event: ScreenEvent.MouseDragged.Pre) {
}
}
fun onMouseScrolled(event: ScreenEvent.MouseScrolled.Pre) {
internal fun onMouseScrolled(event: ScreenEvent.MouseScrolled.Pre) {
val screen = minecraft.screen as? AbstractContainerScreen<*> ?: return
if (screen is MatteryScreen<*>)
@ -242,7 +242,7 @@ fun onMouseScrolled(event: ScreenEvent.MouseScrolled.Pre) {
}
}
fun onPostScreenInit(event: ScreenEvent.Init.Post) {
internal fun onPostScreenInit(event: ScreenEvent.Init.Post) {
if (!LOGGED_IN) return
inventoryLogic(event)
onceClient {
@ -250,7 +250,7 @@ fun onPostScreenInit(event: ScreenEvent.Init.Post) {
}
}
fun onScreenOpen(event: ScreenEvent.Opening) {
internal fun onScreenOpen(event: ScreenEvent.Opening) {
if (shouldOpenVanillaInventory || minecraft.player?.isCreative == true) {
return
}
@ -266,7 +266,7 @@ private val TOOLTIP_TAG_DISPLAY_HELP = TranslatableComponent("otm.gui.debug.tags
private val TOOLTIP_TAG_DISPLAY_ITEM_TITLE = TranslatableComponent("otm.gui.debug.tags.item.title").withStyle(ChatFormatting.DARK_GRAY)
private val TOOLTIP_TAG_DISPLAY_BLOCK_TITLE = TranslatableComponent("otm.gui.debug.tags.block.title").withStyle(ChatFormatting.DARK_GRAY)
fun tooltipEvent(event: ItemTooltipEvent) {
internal fun tooltipEvent(event: ItemTooltipEvent) {
if (event.flags.isAdvanced && ClientConfig.Tooltip.DISPLAY_TAGS && !event.itemStack.isEmpty) {
val itemTags = ArrayList<TagKey<Item>>()
if (event.itemStack.tags.count() > 0) {

View File

@ -33,7 +33,7 @@ private inline fun check(cond: Boolean, error: () -> String) {
}
}
fun createCursors() {
internal fun createCursors() {
ARROW_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_ARROW_CURSOR)
BEAM_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_IBEAM_CURSOR)
HAND_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_POINTING_HAND_CURSOR)
@ -60,7 +60,7 @@ enum class CursorType(val pointer: LongSupplier) {
}
}
fun onClientPostRender(event: RenderFrameEvent.Post) {
internal fun onClientPostRender(event: RenderFrameEvent.Post) {
if (MODIFIED_CURSOR_FRAMES-- <= 0 && MODIFIED_CURSOR) {
GLFW.glfwSetCursor(minecraft.window.window, ARROW_CURSOR)
MODIFIED_CURSOR = false
@ -116,22 +116,22 @@ fun tickWhileClientPre(condition: () -> Boolean, ticker: () -> Unit) {
tickClientPre(IConditionalTickable.wrap(condition, ticker))
}
fun onClientTickPre(event: ClientTickEvent.Pre) {
internal fun onClientTickPre(event: ClientTickEvent.Pre) {
preTickList.tick()
}
fun onClientTickPost(event: ClientTickEvent.Post) {
internal fun onClientTickPost(event: ClientTickEvent.Post) {
postTickList.tick()
}
fun onClientDisconnected(event: ClientPlayerNetworkEvent.LoggingOut) {
internal fun onClientDisconnected(event: ClientPlayerNetworkEvent.LoggingOut) {
LOGGED_IN = false
preTickList.clear()
postTickList.clear()
}
fun onClientConnected(event: ClientPlayerNetworkEvent.LoggingIn) {
internal fun onClientConnected(event: ClientPlayerNetworkEvent.LoggingIn) {
LOGGED_IN = true
preTickList.clear()

View File

@ -23,10 +23,10 @@ import net.neoforged.neoforge.client.event.RenderGuiLayerEvent
import net.neoforged.neoforge.client.event.ScreenEvent
import net.neoforged.neoforge.client.gui.VanillaGuiLayers
import net.neoforged.neoforge.common.ItemAbilities
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature
import ru.dbotthepony.mc.otm.player.android.feature.NanobotsArmorFeature
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas
import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite
@ -48,7 +48,7 @@ object MatteryGUI {
private val buttonShaker = Random()
fun onScreenRender(event: ScreenEvent.Render.Pre) {
internal fun onScreenRender(event: ScreenEvent.Render.Pre) {
val screen = minecraft.screen as? InBedChatScreen
if (screen == null || (screen.leaveBedButton as Button?) == null) {
@ -80,7 +80,7 @@ object MatteryGUI {
}
}
fun onOpenGUIEvent(event: ScreenEvent.Opening) {
internal fun onOpenGUIEvent(event: ScreenEvent.Opening) {
originalBedButtonX = -1
originalBedButtonY = -1
@ -95,7 +95,7 @@ object MatteryGUI {
}
}
fun onLayerRenderEvent(event: RenderGuiLayerEvent.Pre) {
internal fun onLayerRenderEvent(event: RenderGuiLayerEvent.Pre) {
if (minecraft.player?.matteryPlayer?.isAndroid == true) {
if (event.name == VanillaGuiLayers.FOOD_LEVEL
|| event.name == VanillaGuiLayers.AIR_LEVEL
@ -105,7 +105,7 @@ object MatteryGUI {
}
}
fun registerGuiLayers(event: RegisterGuiLayersEvent) {
internal fun registerGuiLayers(event: RegisterGuiLayersEvent) {
event.registerBelow(VanillaGuiLayers.FOOD_LEVEL, loc("android_energy_bar"), AndroidEnergyBarLayer())
event.registerBelow(VanillaGuiLayers.PLAYER_HEALTH, loc("android_health_bar"), AndroidHealthBarLayer())

View File

@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
import kotlin.math.ceil
object MatteryTooltipComponents {
fun gatherComponents(event: RenderTooltipEvent.GatherComponents) {
internal fun gatherComponents(event: RenderTooltipEvent.GatherComponents) {
val energyCap = event.itemStack.getCapability(MatteryCapability.ITEM_ENERGY)
if (energyCap != null && energyCap.maxBatteryLevel > Decimal.ZERO) {
event.tooltipElements.add(1, Either.right(EnergyStorageGaugeTooltip(energyCap)))
@ -29,7 +29,7 @@ object MatteryTooltipComponents {
}
}
fun registerComponents(event: RegisterClientTooltipComponentFactoriesEvent) {
internal fun registerComponents(event: RegisterClientTooltipComponentFactoriesEvent) {
event.register(EnergyStorageGaugeTooltip::class.java) { it }
event.register(MatterStorageGaugeTooltip::class.java) { it }
}

View File

@ -79,7 +79,7 @@ class ChartTooltipElement(
}
companion object {
fun register(event: RegisterClientTooltipComponentFactoriesEvent) {
internal fun register(event: RegisterClientTooltipComponentFactoriesEvent) {
event.register(ChartTooltipElement::class.java) { it }
}
}

View File

@ -11,8 +11,8 @@ import net.minecraft.client.renderer.GameRenderer
import net.minecraft.world.level.levelgen.XoroshiroRandomSource
import net.minecraft.world.level.material.FogType
import org.joml.Matrix4f
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.math.linearInterpolation
import ru.dbotthepony.mc.otm.milliTime

View File

@ -14,6 +14,8 @@ import net.minecraft.world.inventory.tooltip.TooltipComponent
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.screen.panels.ScreenPos
import java.util.Arrays
import kotlin.math.PI
import kotlin.math.roundToInt
@ -45,6 +47,73 @@ class MGUIGraphics(val parent: GuiGraphics) {
drawLine(pose.last().pose(), startX, startY, endX, endY, width, z, color)
}
fun drawLine(
points: Iterable<LinePoint>,
width: Float,
color: RGBAColor = RGBAColor.WHITE
) {
drawLine(pose.last().pose(), points, width, color)
}
fun drawLine(
points: Array<out LinePoint>,
width: Float,
color: RGBAColor = RGBAColor.WHITE
) {
drawLine(pose.last().pose(), points, width, color)
}
fun drawLine(
width: Float,
color: RGBAColor,
vararg points: LinePoint,
) {
drawLine(pose.last().pose(), points, width, color)
}
fun drawLine(
width: Float,
color: RGBAColor,
points: Iterable<LinePoint>,
) {
drawLine(pose.last().pose(), points, width, color)
}
fun drawLine(
width: Float,
color: RGBAColor,
z: Float,
points: List<ScreenPos>,
) {
require(points.size >= 2) { "Degenerate point list: only ${points.size} defined" }
val result = ArrayList<LinePoint>(points.size)
for (i in 1 until points.size) {
val (x0, y0) = points[i - 1]
val (x1, y1) = points[i]
result.add(
LinePoint(
x0, y0,
x1, y1,
z
)
)
}
drawLine(pose.last().pose(), result, width, color)
}
fun drawLine(
width: Float,
color: RGBAColor,
z: Float,
vararg points: ScreenPos,
) {
drawLine(width, color, z, Arrays.asList(*points))
}
fun renderRect(
x: Float,
y: Float,

View File

@ -294,6 +294,65 @@ fun renderColoredSphere(pose: PoseStack, radius: Float, color: RGBAColor = RGBAC
BufferUploader.drawWithShader(builder.buildOrThrow())
}
private fun uploadLineSegment(
builder: BufferBuilder,
matrix: Matrix4f,
startX: Float,
startY: Float,
endX: Float,
endY: Float,
width: Float,
z: Float,
color: RGBAColor = RGBAColor.WHITE
) {
val length = ((startX - endX).pow(2f) + (startY - endY).pow(2f)).pow(0.5f)
var angle = acos((endX - startX) / length)
if (startY > endY)
angle *= -1f
val cos = cos(angle)
val sin = sin(angle)
val y0 = -width
val y1 = width
val x2 = length
val y2 = width
val x3 = length
val y3 = -width
builder.vertex(matrix,
startX - y0 * sin,
startY + y0 * cos,
z).color(color)
builder.vertex(matrix,
startX - y1 * sin,
startY + y1 * cos,
z).color(color)
builder.vertex(matrix,
startX + x2 * cos - y2 * sin,
startY + x2 * sin + y2 * cos,
z).color(color)
builder.vertex(matrix,
startX + x3 * cos - y3 * sin,
startY + x3 * sin + y3 * cos,
z).color(color)
}
data class LinePoint(
val startX: Float,
val startY: Float,
val endX: Float,
val endY: Float,
val z: Float = 0f,
)
fun drawLine(
matrix: Matrix4f,
startX: Float,
@ -312,46 +371,46 @@ fun drawLine(
RenderSystem.depthFunc(GL_ALWAYS)
val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR)
uploadLineSegment(builder, matrix, startX, startY, endX, endY, width, z, color)
BufferUploader.drawWithShader(builder.buildOrThrow())
}
val length = ((startX - endX).pow(2f) + (startY - endY).pow(2f)).pow(0.5f)
val angle = acos((endX - startX) / length)
fun drawLine(
matrix: Matrix4f,
points: Iterable<LinePoint>,
width: Float,
color: RGBAColor = RGBAColor.WHITE
) {
val itr = points.iterator()
val cos = cos(angle)
val sin = sin(angle)
if (!itr.hasNext()) {
throw IllegalArgumentException("No line points were provided")
}
val y0 = -width
RenderSystem.setShader(GameRenderer::getPositionColorShader)
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
val y1 = width
if (!is3DContext)
RenderSystem.depthFunc(GL_ALWAYS)
val x2 = length
val y2 = width
val builder = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR)
val x3 = length
val y3 = -width
builder.vertex(matrix,
startX - y0 * sin,
startY + y0 * cos,
z).color(color)
builder.vertex(matrix,
startX - y1 * sin,
startY + y1 * cos,
z).color(color)
builder.vertex(matrix,
startX + x2 * cos - y2 * sin,
startY + x2 * sin + y2 * cos,
z).color(color)
builder.vertex(matrix,
startX + x3 * cos - y3 * sin,
startY + x3 * sin + y3 * cos,
z).color(color)
for ((startX, startY, endX, endY, z) in itr)
uploadLineSegment(builder, matrix, startX, startY, endX, endY, width, z, color)
BufferUploader.drawWithShader(builder.buildOrThrow())
}
fun drawLine(
matrix: Matrix4f,
points: Array<out LinePoint>,
width: Float,
color: RGBAColor = RGBAColor.WHITE
) {
return drawLine(matrix, points.asIterable(), width, color)
}
data class ScissorRect(val xStart: Int, val yStart: Int, val xEnd: Int, val yEnd: Int, val lock: Boolean = false) {
val width: Int
get() = (xEnd - xStart).coerceAtLeast(0)

View File

@ -7,7 +7,7 @@ import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.renderer.GameRenderer
import net.neoforged.neoforge.client.event.RenderLevelStageEvent
import org.lwjgl.opengl.GL11.GL_LESS
import ru.dbotthepony.mc.otm.config.AndroidConfig
import ru.dbotthepony.mc.otm.config.PlayerConfig
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.math.component1
import ru.dbotthepony.mc.otm.core.math.component2
@ -63,7 +63,7 @@ object ShockwaveRenderer {
private const val EXPANSION_PER_SECOND = 18f
fun onRender(event: RenderLevelStageEvent) {
internal fun onRender(event: RenderLevelStageEvent) {
if (event.stage !== RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) {
return
}
@ -74,6 +74,6 @@ object ShockwaveRenderer {
}
fun handle(packet: ShockwaveEffectPacket) {
State(packet.pos, AndroidConfig.Shockwave.RADIUS_HORIZONTAL.toFloat())
State(packet.pos, PlayerConfig.Shockwave.RADIUS_HORIZONTAL.toFloat())
}
}

View File

@ -5,7 +5,7 @@ import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas
import ru.dbotthepony.mc.otm.core.ResourceLocation
object WidgetLocation {
val STORAGE_CONTROLS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/storage_controls.png"), 90f, 72f)
val STORAGE_CONTROLS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/storage_controls.png"), 90f, 90f)
val WIDGET_18 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/widget_18.png"), 72f, 72f)
val WIDGET_15 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/widget_15.png"), 60f, 60f)
val WIDGET_8 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/widget_8.png"), 64f, 32f)

View File

@ -6,7 +6,7 @@ import ru.dbotthepony.mc.otm.core.immutableMap
import ru.dbotthepony.mc.otm.core.math.RelativeSide
object Widgets18 {
private val storageGrid = WidgetLocation.STORAGE_CONTROLS.grid(rows = 4, columns = 5)
private val storageGrid = WidgetLocation.STORAGE_CONTROLS.grid(rows = 5, columns = 5)
val SORT_DESCENDING = storageGrid.next()
val SORT_ASCENDING = storageGrid.next()
@ -24,6 +24,13 @@ object Widgets18 {
val PLAY = storageGrid.next()
val STOP = storageGrid.next()
val SORT_NOW = storageGrid.next()
val MOVE_EVERYTHING_TO_STORAGE = storageGrid.next()
val MOVE_EVERYTHING_FROM_STORAGE = storageGrid.next()
val RESTOCK_TO_STORAGE = storageGrid.next()
val RESTOCK_FROM_STORAGE = storageGrid.next()
val RESTOCK_WITH_MOVE_TO_STORAGE = storageGrid.next()
val RESTOCK_WITH_MOVE_FROM_STORAGE = storageGrid.next()
val SMART_STORAGE_EXCHANGE = storageGrid.next()
private val miscGrid = WidgetLocation.WIDGET_18.grid(4, 4)

View File

@ -142,7 +142,7 @@ class BatteryBankRenderer(context: BlockEntityRendererProvider.Context) : BankRe
override val texture: AbstractMatterySprite = WidgetLocation.VERTICAL_GAUGES.sprite(x = 108f, width = 18f)
companion object {
fun onRegisterAdditionalModels(event: ModelEvent.RegisterAdditional) {
internal fun onRegisterAdditionalModels(event: ModelEvent.RegisterAdditional) {
for (i in 0 .. 11) {
event.register(ModelResourceLocation.standalone(ResourceLocation(OverdriveThatMatters.MOD_ID, "block/battery/battery$i")))
}
@ -168,7 +168,7 @@ class MatterBatteryBankRenderer(context: BlockEntityRendererProvider.Context) :
override val texture: AbstractMatterySprite = WidgetLocation.VERTICAL_GAUGES.sprite(x = 90f, width = 18f)
companion object {
fun onRegisterAdditionalModels(event: ModelEvent.RegisterAdditional) {
internal fun onRegisterAdditionalModels(event: ModelEvent.RegisterAdditional) {
for (i in 0 .. 11) {
event.register(ModelResourceLocation.standalone(ResourceLocation(OverdriveThatMatters.MOD_ID, "block/battery/matter_capacitor$i")))
}

View File

@ -15,7 +15,7 @@ import org.lwjgl.opengl.GL30
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.ShiftPressedCond
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.*

View File

@ -20,12 +20,13 @@ import ru.dbotthepony.mc.otm.core.math.asAngle
import ru.dbotthepony.mc.otm.core.math.clusterize
import ru.dbotthepony.mc.otm.core.util.formatPower
import ru.dbotthepony.mc.otm.core.math.times
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
import java.util.Random
import kotlin.math.PI
import kotlin.math.absoluteValue
class EnergyCounterRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<EnergyCounterBlockEntity> {
private val random = Random()
private val random = GJRAND64RandomSource()
override fun render(
tile: EnergyCounterBlockEntity,

View File

@ -17,9 +17,11 @@ import net.neoforged.neoforge.common.NeoForge
import org.lwjgl.opengl.GL11
import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.moveMousePosScaled
import ru.dbotthepony.mc.otm.client.render.LinePoint
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.render.translation
@ -55,6 +57,7 @@ import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.collections.ArrayList
import kotlin.collections.List
import kotlin.collections.MutableSet
import kotlin.collections.isNotEmpty
@ -690,7 +693,13 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
for (panel in panelsReversed) {
RenderSystem.depthFunc(GL11.GL_ALWAYS)
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
panel.render(wrap, mouseXf, mouseYf, partialTick)
val segments = ArrayList<LinePoint>()
panel.render(wrap, mouseXf, mouseYf, partialTick, segments)
if (segments.isNotEmpty()) {
wrap.drawLine(0.5f, RGBAColor.GOLD, segments)
}
}
if (!panelsReversed.any { it.updateCursor0() })

View File

@ -52,7 +52,7 @@ open class DecimalHistoryChartPanel<out S : MatteryScreen<*>>(
map[1f] = formatText(maximum)
for (cluster in chart.asIterable().clusterize(randomGenerator)) {
for (cluster in chart.asIterable().clusterize(random)) {
val perc = (cluster.center / maximum).toFloat()
if (map.keys.none { (it - perc).absoluteValue < 0.08f }) {

View File

@ -11,94 +11,31 @@ import net.minecraft.client.gui.components.events.GuiEventListener
import net.minecraft.client.gui.navigation.FocusNavigationEvent
import net.minecraft.client.gui.navigation.ScreenRectangle
import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.renderer.Rect2i
import net.minecraft.network.chat.Component
import net.minecraft.util.RandomSource
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.SystemTime
import ru.dbotthepony.mc.otm.client.CursorType
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.moveMousePosScaled
import ru.dbotthepony.mc.otm.client.render.LinePoint
import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.currentScissorRect
import ru.dbotthepony.mc.otm.client.render.popScissorRect
import ru.dbotthepony.mc.otm.client.render.pushScissorRect
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.input.QueryUserPanel
import ru.dbotthepony.mc.otm.core.RandomSource2Generator
import ru.dbotthepony.mc.otm.core.collect.concatIterators
import ru.dbotthepony.mc.otm.core.collect.flatMap
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
import java.util.function.Predicate
import java.util.random.RandomGenerator
import kotlin.collections.ArrayList
import kotlin.math.max
import kotlin.math.roundToInt
data class ScreenPos(val x: Float, val y: Float)
data class DockProperty(val left: Float = 0f, val top: Float = 0f, val right: Float = 0f, val bottom: Float = 0f) {
val isEmpty get() = left == 0f && right == 0f && top == 0f && bottom == 0f
val horizontal get() = left + right
val vertical get() = top + bottom
operator fun plus(other: DockProperty): DockProperty {
return DockProperty(
left + other.left,
top + other.top,
right + other.right,
bottom + other.bottom
)
}
operator fun minus(other: DockProperty): DockProperty {
return DockProperty(
left - other.left,
top - other.top,
right - other.right,
bottom - other.bottom
)
}
operator fun plus(other: Float): DockProperty {
return DockProperty(
left + other,
top + other,
right + other,
bottom + other
)
}
operator fun minus(other: Float): DockProperty {
return DockProperty(
left - other,
top - other,
right - other,
bottom - other
)
}
companion object {
val EMPTY = DockProperty()
}
}
enum class Dock {
NONE, LEFT, RIGHT, TOP, BOTTOM, FILL
}
enum class DockResizeMode(val changeWidth: Boolean, val changeHeight: Boolean) {
ALL(true, true), NONE(false, false), WIDTH(true, false), HEIGHT(false, true)
}
data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) {
fun toIntRect(): Rect2i {
return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt())
}
}
open class EditablePanel<out S : Screen>(
val screen: S,
parent: EditablePanel<*>?,
@ -175,18 +112,14 @@ open class EditablePanel<out S : Screen>(
}
}
val random: RandomSource by lazy {
val random: GJRAND64RandomSource by lazy {
if (screen is MatteryScreen<*>) {
screen.menu.random
} else {
RandomSource.create()
GJRAND64RandomSource()
}
}
val randomGenerator: RandomGenerator by lazy {
RandomSource2Generator(random)
}
/**
* Bigger values means lesser priority while docking, rendering and processing inputs.
*/
@ -350,11 +283,13 @@ open class EditablePanel<out S : Screen>(
if (visibleChildrenParent?.contains(this) == false) {
visibleChildrenParent.add(this)
parent?.invalidateChildrenSorting()
parent?.layoutInvalidated = true
}
} else {
if (visibleChildrenParent?.contains(this) == true) {
visibleChildrenParent.remove(this)
parent?.invalidateChildrenSorting()
parent?.layoutInvalidated = true
}
}
@ -843,6 +778,12 @@ open class EditablePanel<out S : Screen>(
childrenSortingInvalidated = true
}
protected open fun onChildrenAdded(child: EditablePanel<*>) {}
protected open fun onChildrenRemoved(child: EditablePanel<*>) {}
protected open fun onParented(parent: EditablePanel<*>) {}
protected open fun onUnParented(parent: EditablePanel<*>) {}
private fun onParent(child: EditablePanel<*>) {
if (childrenInternal.contains(child)) throw IllegalStateException("Already containing $child")
childrenInternal.add(child)
@ -860,11 +801,15 @@ open class EditablePanel<out S : Screen>(
else
updateVisibility = true
}
onChildrenAdded(child)
child.onParented(this)
}
private fun onUnParent(child: EditablePanel<*>) {
val indexOf = childrenInternal.indexOf(child)
if (indexOf == -1) throw IllegalStateException("Already not containing $child")
child.onUnParented(this)
childrenInternal.removeAt(indexOf)
invalidateChildrenSorting()
@ -876,6 +821,8 @@ open class EditablePanel<out S : Screen>(
if (child.isVisible() != isVisible()) {
updateVisible()
}
onChildrenRemoved(child)
}
private fun sortChildren() {
@ -944,12 +891,11 @@ open class EditablePanel<out S : Screen>(
}
}
fun render(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
fun render(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float, debugSegments: MutableList<LinePoint>) {
once = true
if (!isVisible()) {
if (!isVisible())
return
}
val poseStack = graphics.pose
@ -997,12 +943,19 @@ open class EditablePanel<out S : Screen>(
child.absoluteX = absoluteX + child.x + xOffset
child.absoluteY = absoluteY + child.y + yOffset
child.render(graphics, mouseX, mouseY, partialTick)
child.render(graphics, mouseX, mouseY, partialTick, debugSegments)
}
if (scissor) {
popScissorRect()
}
if (minecraft.entityRenderDispatcher.shouldRenderHitBoxes()) {
debugSegments.add(LinePoint(absoluteX, absoluteY, absoluteX + width, absoluteY))
debugSegments.add(LinePoint(absoluteX + width, absoluteY, absoluteX + width, absoluteY + height))
debugSegments.add(LinePoint(absoluteX + width, absoluteY + height, absoluteX, absoluteY + height))
debugSegments.add(LinePoint(absoluteX, absoluteY + height, absoluteX, absoluteY))
}
}
fun updateCursor0(): Boolean {
@ -1508,6 +1461,7 @@ open class EditablePanel<out S : Screen>(
if (old != new) {
child.visibilityChanges(new, old)
child.invalidateChildrenSorting()
}
child.updateVisible()

View File

@ -6,8 +6,8 @@ import net.minecraft.client.gui.screens.inventory.InventoryScreen
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.Widgets8
import ru.dbotthepony.mc.otm.client.render.sprites.sprite

View File

@ -4,6 +4,8 @@ import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.Renderable
import net.minecraft.client.gui.components.events.GuiEventListener
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.render.LinePoint
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
// before 1.19.3 Renderable was Widget
@ -21,11 +23,17 @@ class Panel2Widget<out S: Screen, out P : EditablePanel<S>>(
val yFloat = mouseY.toFloat()
val wrap = MGUIGraphics(graphics)
val segments = ArrayList<LinePoint>()
panel.tickHovered0(xFloat, yFloat, false)
panel.tickHovered1()
panel.tickHovered2()
panel.render(wrap, xFloat, yFloat, partialTick)
panel.render(wrap, xFloat, yFloat, partialTick, segments)
if (segments.isNotEmpty()) {
wrap.drawLine(0.5f, RGBAColor.GOLD, segments)
}
panel.renderTooltips(wrap, xFloat, yFloat, partialTick)
}

View File

@ -0,0 +1,115 @@
package ru.dbotthepony.mc.otm.client.screen.panels
import net.minecraft.client.renderer.Rect2i
import kotlin.math.roundToInt
data class ScreenPos(val x: Float, val y: Float)
data class DockProperty(val left: Float = 0f, val top: Float = 0f, val right: Float = 0f, val bottom: Float = 0f) {
val isEmpty get() = left == 0f && right == 0f && top == 0f && bottom == 0f
val horizontal get() = left + right
val vertical get() = top + bottom
operator fun plus(other: DockProperty): DockProperty {
return DockProperty(
left + other.left,
top + other.top,
right + other.right,
bottom + other.bottom
)
}
operator fun minus(other: DockProperty): DockProperty {
return DockProperty(
left - other.left,
top - other.top,
right - other.right,
bottom - other.bottom
)
}
operator fun plus(other: Float): DockProperty {
return DockProperty(
left + other,
top + other,
right + other,
bottom + other
)
}
operator fun minus(other: Float): DockProperty {
return DockProperty(
left - other,
top - other,
right - other,
bottom - other
)
}
companion object {
val EMPTY = DockProperty()
@JvmStatic
fun all(value: Float): DockProperty {
return DockProperty(value, value, value, value)
}
@JvmStatic
@JvmOverloads
fun topLeft(top: Float, left: Float = top): DockProperty {
return DockProperty(left = left, top = top)
}
@JvmStatic
fun left(value: Float): DockProperty {
return DockProperty(left = value)
}
@JvmStatic
@JvmOverloads
fun topRight(top: Float, right: Float = top): DockProperty {
return DockProperty(right = right, top = top)
}
@JvmStatic
fun right(value: Float): DockProperty {
return DockProperty(right = value)
}
@JvmStatic
fun top(value: Float): DockProperty {
return DockProperty(top = value)
}
@JvmStatic
@JvmOverloads
fun bottomLeft(bottom: Float, left: Float = bottom): DockProperty {
return DockProperty(left = left, bottom = bottom)
}
@JvmStatic
@JvmOverloads
fun bottomRight(bottom: Float, right: Float = bottom): DockProperty {
return DockProperty(right = right, bottom = bottom)
}
@JvmStatic
fun bottom(value: Float): DockProperty {
return DockProperty(bottom = value)
}
}
}
enum class Dock {
NONE, LEFT, RIGHT, TOP, BOTTOM, FILL
}
enum class DockResizeMode(val changeWidth: Boolean, val changeHeight: Boolean) {
ALL(true, true), NONE(false, false), WIDTH(true, false), HEIGHT(false, true)
}
data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) {
fun toIntRect(): Rect2i {
return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt())
}
}

View File

@ -7,6 +7,9 @@ import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.maybe
import java.util.stream.IntStream
import java.util.stream.Stream
import kotlin.math.max
open class GridPanel<out S : Screen>(
screen: S,
@ -20,25 +23,150 @@ open class GridPanel<out S : Screen>(
) : EditablePanel<S>(screen, parent, x, y, width, height) {
var columns: Int = columns
set(value) {
field = value
invalidateLayout()
if (field != value) {
field = value
invalidateLayout()
}
}
var rows: Int = rows
set(value) {
field = value
invalidateLayout()
if (field != value) {
field = value
invalidateLayout()
}
}
var gravity: RenderGravity = RenderGravity.CENTER_CENTER
set(value) {
field = value
invalidateLayout()
if (field != value) {
field = value
invalidateLayout()
}
}
var layout: Layout = Layout.TOP_LEFT
set(value) {
if (field != value) {
field = value
invalidateLayout()
}
}
var columnMajorOrder = false
set(value) {
if (field != value) {
field = value
invalidateLayout()
}
}
enum class Layout {
TOP_LEFT {
override fun get(
list: List<EditablePanel<*>>,
row: Int,
column: Int,
rows: Int,
columns: Int,
columnMajorOrder: Boolean
): EditablePanel<*>? {
if (columnMajorOrder) {
return list.getOrNull(row + column * rows)
} else {
return list.getOrNull(column + row * columns)
}
}
},
TOP_RIGHT {
override fun get(
list: List<EditablePanel<*>>,
row: Int,
column: Int,
rows: Int,
columns: Int,
columnMajorOrder: Boolean
): EditablePanel<*>? {
if (columnMajorOrder) {
return list.getOrNull(row + (columns - column - 1) * rows)
} else {
return list.getOrNull((columns - column - 1) + row * columns)
}
}
},
BOTTOM_LEFT {
override fun get(
list: List<EditablePanel<*>>,
row: Int,
column: Int,
rows: Int,
columns: Int,
columnMajorOrder: Boolean
): EditablePanel<*>? {
if (columnMajorOrder) {
return list.getOrNull((rows - row - 1) + column * rows)
} else {
return list.getOrNull(column + (rows - row - 1) * columns)
}
}
},
BOTTOM_RIGHT {
override fun get(
list: List<EditablePanel<*>>,
row: Int,
column: Int,
rows: Int,
columns: Int,
columnMajorOrder: Boolean
): EditablePanel<*>? {
if (columnMajorOrder) {
return list.getOrNull((rows - row - 1) + (columns - column - 1) * rows)
} else {
return list.getOrNull((columns - column - 1) + (rows - row - 1) * columns)
}
}
};
abstract fun get(list: List<EditablePanel<*>>, row: Int, column: Int, rows: Int, columns: Int, columnMajorOrder: Boolean): EditablePanel<*>?
}
override fun sizeToContents() {
if (visibleChildren.isEmpty()) {
// nothing to size against
return
}
visibleChildren.forEach { it.sizeToContents() }
var width = 0f
var height = 0f
val children = visibleChildren.filter { it.dock == Dock.NONE }
for (row in 0 until rows) {
var maxHeight = 0f
var rowWidth = 0f
for (column in 0 until columns) {
val nextChild = layout.get(children, row, column, rows, columns, columnMajorOrder) ?: continue
rowWidth += nextChild.width + nextChild.dockMargin.horizontal
maxHeight = max(maxHeight, nextChild.height + nextChild.dockMargin.vertical)
}
height += maxHeight
width = max(width, rowWidth)
}
this.width = width
this.height = height
}
override fun performLayout() {
super.performLayout()
var children = visibleChildren.iterator().filter { it.dock == Dock.NONE }
val children = visibleChildren.filter { it.dock == Dock.NONE }
var totalWidth = 0f
var totalHeight = 0f
@ -48,7 +176,7 @@ open class GridPanel<out S : Screen>(
var width = 0f
for (column in 0 until columns) {
val child = children.maybe() ?: break
val child = layout.get(children, row, column, rows, columns, columnMajorOrder) ?: continue
width += child.dockedWidth
maxHeight = maxHeight.coerceAtLeast(child.dockedHeight)
}
@ -59,7 +187,6 @@ open class GridPanel<out S : Screen>(
val alignX = gravity.repositionX(width, totalWidth)
val alignY = gravity.repositionY(height, totalHeight)
children = visibleChildren.iterator().filter { it.dock == Dock.NONE }
totalWidth = 0f
totalHeight = 0f
@ -69,7 +196,7 @@ open class GridPanel<out S : Screen>(
var width = 0f
for (column in 0 until columns) {
val child = children.maybe() ?: break
val child = layout.get(children, row, column, rows, columns, columnMajorOrder) ?: continue
child.x = alignX + width
child.y = alignY + totalHeight
width += child.dockedWidth

View File

@ -7,15 +7,15 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import net.minecraft.ChatFormatting
import net.minecraft.client.Minecraft
import net.minecraft.network.chat.Component
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.android.AndroidResearch
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.player.android.AndroidResearch
import ru.dbotthepony.mc.otm.player.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.player.android.AndroidResearchType
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.client.CursorType
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
@ -33,9 +33,9 @@ import ru.dbotthepony.mc.otm.client.screen.panels.util.DraggableCanvasPanel
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.core.RandomSource2Generator
import ru.dbotthepony.mc.otm.core.nextFloat
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
import java.util.*
@ -542,14 +542,14 @@ class AndroidStationScreen(p_97741_: AndroidStationMenu, p_97742_: Inventory, p_
if (isPreview && !layoutInvalidated) {
if (firstTick) {
scroller.init.invoke(this, randomGenerator)
scroller.init.invoke(this, random)
}
val status = scroller.scroll.invoke(this, randomGenerator)
val status = scroller.scroll.invoke(this, random)
if (!status) {
scroller = PreviewScrollers.entries.let { it[random.nextInt(it.size)] }
scroller.init.invoke(this, randomGenerator)
scroller.init.invoke(this, random)
}
}
}

View File

@ -12,7 +12,7 @@ import net.neoforged.fml.ModList
import net.neoforged.fml.loading.FMLEnvironment
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite
import ru.dbotthepony.mc.otm.client.render.sprites.sprite
@ -40,15 +40,11 @@ val isCuriosLoaded by lazy {
ModList.get().isLoaded(CuriosApi.MODID)
}
fun onCuriosSlotModifiersUpdated(event: SlotModifiersUpdatedEvent) {
internal fun onCuriosSlotModifiersUpdated(event: SlotModifiersUpdatedEvent) {
check(isCuriosLoaded) { "Curios is not loaded!" }
event.entity.matteryPlayer?.recreateExoPackMenu()
}
fun openCuriosScreen(carriedStack: ItemStack = ItemStack.EMPTY) {
if (FMLEnvironment.dist.isClient) PacketDistributor.sendToServer(CPacketOpenCurios(carriedStack))
}
private fun Player.getCuriosSlotsImpl(): List<PlayerSlot<Slot, Slot>> {
val handler = getCapability(CuriosCapability.INVENTORY) ?: return listOf()

View File

@ -18,8 +18,8 @@ import net.minecraft.world.item.Items
import net.neoforged.neoforge.network.handling.IPayloadContext
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot

View File

@ -99,7 +99,7 @@ class MatteryChestMenu(
return MatteryChestMenu(HOPPER, containerId, inventory, 1, 5, container)
}
fun register(bus: IEventBus) {
internal fun register(bus: IEventBus) {
registrar.register(bus)
bus.addListener(this::registerScreens)
}

View File

@ -0,0 +1,9 @@
package ru.dbotthepony.mc.otm.config
interface IFoodRegenerationValues {
val foodLimit: Int
val requiresSaturation: Boolean
val ticks: Int
val regenerationSlowdown: Boolean
val upperSlowdownBound: Double
}

View File

@ -4,16 +4,31 @@ import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
object AndroidConfig : AbstractConfig("androids") {
object PlayerConfig : AbstractConfig("player") {
init {
builder.push("Android")
}
val REGENERATE_ENERGY: Boolean by builder
.comment("If (technically) hunger is above threshold, it turns into energy")
.comment("This setting controls whenever to regenerate small amount of energy while eating as Android")
.comment("And also whenever to regenerate energy while in peaceful")
.comment("If this is disabled, any (technically) excess hunger will be nullified, unless playing on peaceful difficulty.")
.define("REGENERATE_ENERGY", true)
val REGENERATE_ENERGY_EFFICIENCY_FOOD: Double by builder
.comment("How much % of food points to convert to energy")
.defineInRange("REGENERATE_ENERGY_EFFICIENCY_FOOD", 0.4, 0.0)
val REGENERATE_ENERGY_EFFICIENCY_SATURATION: Double by builder
.comment("How much % of food saturation points to convert to energy")
.defineInRange("REGENERATE_ENERGY_EFFICIENCY_SATURATION", 0.2, 0.0)
val REGENERATE_ENERGY_IN_PEACEFUL: Boolean by builder
.comment("Regenerate energy while in peaceful")
.comment("This is disabled by default because this is easily exploitable")
.define("REGENERATE_ENERGY_IN_PEACEFUL", false)
val TIME_BETWEEN_NATURAL_REGENERATION: Int by builder
.comment("Time in ticks between natural health regeneration ticks")
.comment("Time in ticks between natural health regeneration ticks for Android")
.comment("Default value is meant to be one of downsides of being an android,")
.comment("so please, don't blindly buff it, players have ability to research into Nanobots Regeneration,")
.comment("which provide superior regeneration on average than human players.")
@ -24,6 +39,32 @@ object AndroidConfig : AbstractConfig("androids") {
.comment("for android players, since 'hunger' (for compatibility) is managed by mod in such case")
.defineInRange("TIME_BETWEEN_NATURAL_REGENERATION", 120, 0, Int.MAX_VALUE)
val ANDROID_ENERGY_PER_HUNGER_POINT by builder.defineDecimal("energyPerHunger", Decimal(2000), Decimal.ZERO)
val ANDROID_MAX_ENERGY by builder
.comment("Internal battery of every android has this much storage")
.comment("Keep in mind that already existing players won't get their value changed since it is", "stored inside their savedata")
.defineDecimal("capacity", Decimal(80_000), Decimal.ZERO)
val NIGHT_VISION_POWER_DRAW by builder.defineDecimal("nightVisionPowerDraw", Decimal(8), Decimal.ZERO)
val FALL_DAMAGE_REDUCTION_PER_LEVEL_P: Double by builder
.comment("In percent. Level of feature is multiplied by this")
.comment("First, fall damage is reduced by flat resistance, then reduced by percentage resistance (this)")
.defineInRange("FALL_DAMAGE_REDUCTION_PER_LEVEL_P", 0.2, 0.01, 1.0)
val FALL_DAMAGE_REDUCTION_PER_LEVEL_F: Double by builder
.comment("In flat half of hearts. Level of feature is multiplied by this")
.comment("First, fall damage is reduced by flat resistance (this), then reduced by percentage resistance")
.defineInRange("FALL_DAMAGE_REDUCTION_PER_LEVEL_F", 1.5, 0.0, Float.MAX_VALUE.toDouble())
val SWIM_BOOSTERS: Double by builder
.comment("Increase per level")
.defineInRange("SWIM_BOOSTERS", 0.25, 0.0, Float.MAX_VALUE.toDouble())
init {
builder.pop()
}
object NanobotsRegeneration {
init {
builder.push("NanobotsRegeneration")
@ -52,27 +93,6 @@ object AndroidConfig : AbstractConfig("androids") {
}
}
val ANDROID_ENERGY_PER_HUNGER_POINT by builder.defineDecimal("energyPerHunger", Decimal(2000), Decimal.ZERO)
val ANDROID_MAX_ENERGY by builder
.comment("Internal battery of every android has this much storage")
.comment("Keep in mind that already existing players won't get their value changed since it is", "stored inside their savedata")
.defineDecimal("capacity", Decimal(80_000), Decimal.ZERO)
val NIGHT_VISION_POWER_DRAW by builder.defineDecimal("nightVisionPowerDraw", Decimal(8), Decimal.ZERO)
val FALL_DAMAGE_REDUCTION_PER_LEVEL_P: Double by builder
.comment("In percent. Level of feature is multiplied by this")
.comment("First, fall damage is reduced by flat resistance, then reduced by percentage resistance (this)")
.defineInRange("FALL_DAMAGE_REDUCTION_PER_LEVEL_P", 0.2, 0.01, 1.0)
val FALL_DAMAGE_REDUCTION_PER_LEVEL_F: Double by builder
.comment("In flat half of hearts. Level of feature is multiplied by this")
.comment("First, fall damage is reduced by flat resistance (this), then reduced by percentage resistance")
.defineInRange("FALL_DAMAGE_REDUCTION_PER_LEVEL_F", 1.5, 0.0, Float.MAX_VALUE.toDouble())
val SWIM_BOOSTERS: Double by builder
.comment("Increase per level")
.defineInRange("SWIM_BOOSTERS", 0.25, 0.0, Float.MAX_VALUE.toDouble())
object EnderTeleporter {
init {
builder.comment("Ender Teleporter ability").push("EnderTeleporter")
@ -148,4 +168,103 @@ object AndroidConfig : AbstractConfig("androids") {
Magnet
Shockwave
}
object Food {
init {
builder
.comment("Food related tweaks")
.comment("Since OTM overrides FoodData logic (to make room for Android logic)")
.comment("these settings are provided for tweaking FoodData behavior")
.push("Food")
}
val SOFT_FOOD_LIMIT: Int by builder
.comment("Soft food points limit, which dictate upper bound where player is considered 'hungry',")
.comment("e.g. they can eat food which is not marked as 'can always eat'")
.defineInRange("SOFT_FOOD_LIMIT", 20, 0)
val HARD_FOOD_LIMIT: Int by builder
.comment("Hard food points limit, which dictate upper bound of food points,")
.comment("e.g. hunger can not go above this value")
.comment("This is extremely buffed in OTM by default to remove annoyance regarding consuming foodstuffs")
.comment("when you are running low on food, so you can eat high-quality food without fear")
.comment("that food points will go to waste (especially when you need to regenerate lots of HP)")
.defineInRange("HARD_FOOD_LIMIT", 40, 1)
val OVERSATURATION_LIMIT: Double by builder
.comment("Controls how much 'saturation' can be stored above hunger level.")
.comment("Negative values will decrease maximum saturation achievable.")
.defineInRange("OVERSATURATION_LIMIT", 0.0, -Float.MAX_VALUE.toDouble() + 1.0, Float.MAX_VALUE.toDouble() - 1.0)
val EXHAUSTION_LIMIT: Double by builder
.comment("Controls technical aspect how much 'exhaustion' player can accumulate")
.comment("This should not be confused with how much 'exhaustion' is considered as 1 hunger point")
.comment("Usually, this should not be changed, since it is a very technical detail;")
.comment("but if you have a mod installed which easily hits this limit (and somehow hunger system can't keep up,)")
.comment("e.g. it pushes exhaustion over its limit in one call), you can increase this value")
.defineInRange("EXHAUSTION_LIMIT", 40.0, 4.0, Float.MAX_VALUE.toDouble() - 1.0)
private fun defineRegeneration(
threshold: Int,
requiresSaturation: Boolean,
ticks: Int,
): IFoodRegenerationValues {
return object : IFoodRegenerationValues {
override val foodLimit: Int by builder
.defineInRange("FOOD_THRESHOLD", threshold, 1)
override val requiresSaturation: Boolean by builder
.define("REQUIRES_SATURATION", requiresSaturation)
override val ticks: Int by builder
.defineInRange("TICKS", ticks, 0)
override val regenerationSlowdown: Boolean by builder
.comment("Slowdown regeneration based on remaining saturation (given REQUIRES_SATURATION is true)")
.comment("This replicates vanilla behavior where fast regeneration speed linearly slowdowns the moment")
.comment("saturation falls below 6 hunger points (configurable through SATURATION_SLOWDOWN_BOUND)")
.comment("This is disabled in OTM by default to buff humans compared to androids when it comes to regeneration")
.define("SATURATION_SLOWDOWN", false)
override val upperSlowdownBound: Double by builder
.defineInRange("SATURATION_SLOWDOWN_BOUND", 6.0, 1.0, Float.MAX_VALUE - 1.0)
}
}
val FAST_REGEN: IFoodRegenerationValues
val SLOW_REGEN: IFoodRegenerationValues
init {
builder.push("FAST_REGENERATION")
FAST_REGEN = defineRegeneration(20, true, 10)
builder.pop()
builder.push("SLOW_REGENERATION")
SLOW_REGEN = defineRegeneration(18, false, 80)
builder.pop()
}
val ENABLE_STARVATION: Boolean by builder
.define("ENABLE_STARVATION", true)
val STARVATION_TICKS: Int by builder
.defineInRange("STARVATION_TICKS", 80, 1)
val STARVATION_HEALTH_LIMIT_EASY: Double by builder
.defineInRange("STARVATION_HEALTH_LIMIT_EASY", 10.0, 0.0)
val STARVATION_HEALTH_LIMIT_NORMAL: Double by builder
.defineInRange("STARVATION_HEALTH_LIMIT_NORMAL", 1.0, 0.0)
val STARVATION_HEALTH_LIMIT_HARD: Double by builder
.defineInRange("STARVATION_HEALTH_LIMIT_HARD", 0.0, 0.0)
init {
builder.pop()
}
}
init {
Food
}
}

View File

@ -83,5 +83,5 @@ object ServerConfig : AbstractConfig("misc") {
val WITHER_SKELETON_SWORD_CHANCE: Double by builder
.comment("Chance of Wither Skeleton spawning with Withered Steel sword")
.defineInRange("WITHER_SKELETON_HELMET_CHANCE", 0.24, 0.0, 1.0)
.defineInRange("WITHER_SKELETON_SWORD_CHANCE", 0.24, 0.0, 1.0)
}

View File

@ -0,0 +1,29 @@
package ru.dbotthepony.mc.otm.core
import net.minecraft.util.RandomSource
import net.minecraft.world.level.Level
import net.neoforged.fml.ModList
interface IMatteryLevel {
val otmRandom: RandomSource?
}
/**
* OTM provided [RandomSource], which has better statistical parameters
*
* Original Minecraft use LCG, which may show bad behavior when repeatedly sampled *a lot*,
* which is what [Level]'s random is used for. OTM provided PRNG should behave better in this scenario.
*
* The way OTM uses random generator in its code will quickly cause LCG used in Minecraft to show its bias
* because LCG in minecraft samples its highest 48 bits, which gives us at best 2^16 period in the lowest bit returned by LCG.
* Which it doesn't sound bad, it quickly causes RNG become biased the quicker/more it is sampled on each tick, especially considering
* some may use `level.random.nextInt(chance) == 0` to determine chance of something happening,
* which will get extremely biased on heavy RNG congested environment
* If we avoid sampling Level's generator this much, we won't suffer from bias in our own code, as well as avoid biasing other mods this much.
*
* The "2^16 period" problem is also might be the reason why Entities get their own instance of RandomSource,
* and Mob Goals use random exactly the way described above (`nextInt(chance)`), which can and will suffer
* from bias the moment mob exists in world for more than 2^16 ticks (but actual bias will happen sooner
* because RNG is not sampled only once per tick, obviously)
*/
val Level.otmRandom: RandomSource get() = (this as IMatteryLevel).otmRandom ?: random

View File

@ -1,6 +1,7 @@
package ru.dbotthepony.mc.otm.core.math
import it.unimi.dsi.fastutil.objects.ObjectArrayList
import net.minecraft.util.RandomSource
import ru.dbotthepony.mc.otm.core.random
import java.util.random.RandomGenerator
import kotlin.math.min
@ -88,7 +89,7 @@ private class MutableCluster<V : Comparable<V>>(var center: V) {
}
private fun <V : Comparable<V>> Iterable<V>.clusterize(
random: RandomGenerator,
random: RandomSource,
initialClusters: Int = 1,
zeroBound: Boolean = false,
identity: V,
@ -202,7 +203,7 @@ private fun <V : Comparable<V>> Iterable<V>.clusterize(
// TODO: could use some tweaking
private val DECIMAL_ERROR_TOLERANCE = Decimal("0.02")
fun Iterable<Decimal>.clusterize(random: RandomGenerator, clusters: Int? = null, zeroBound: Boolean = false): List<Cluster<Decimal>> {
fun Iterable<Decimal>.clusterize(random: RandomSource, clusters: Int? = null, zeroBound: Boolean = false): List<Cluster<Decimal>> {
return clusterize(random, clusters ?: 1, zeroBound, Decimal.ZERO, Decimal::plus, Decimal::minus, Decimal::div, Decimal::absoluteValue) { min, max, error ->
if (clusters != null)
false

View File

@ -9,6 +9,7 @@ import net.minecraft.network.chat.FormattedText
import net.minecraft.network.chat.MutableComponent
import net.minecraft.world.inventory.tooltip.TooltipComponent
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.THREAD_LOCAL_RANDOM
import ru.dbotthepony.mc.otm.client.render.ChartLevelLabels
import ru.dbotthepony.mc.otm.client.render.ChartTooltipElement
import ru.dbotthepony.mc.otm.config.ClientConfig
@ -453,10 +454,8 @@ private fun formatHistoryChart(
labelNames[0f] = (-maxTransferred).formatSiComponent(suffix, decimals, formatAsReadable = verbose, bias = bias)
labelNames[1f] = maxReceived.formatSiComponent(suffix, decimals, formatAsReadable = verbose, bias = bias)
val rand = java.util.Random()
if (maxTransferred.isNotZero && transferredMult > 0.2f) {
for (cluster in widget.transferred.clusterize(rand, zeroBound = true)) {
for (cluster in widget.transferred.clusterize(THREAD_LOCAL_RANDOM, zeroBound = true)) {
val perc = (cluster.center / maxTransferred).toFloat() * transferredMult
if (labelNames.keys.none { (it - perc).absoluteValue < 0.08f })
@ -465,7 +464,7 @@ private fun formatHistoryChart(
}
if (maxReceived.isNotZero && receivedMult > 0.2f) {
for (cluster in widget.received.clusterize(rand, zeroBound = true)) {
for (cluster in widget.received.clusterize(THREAD_LOCAL_RANDOM, zeroBound = true)) {
val perc = zero + (cluster.center / maxReceived).toFloat() * receivedMult
if (labelNames.keys.none { (it - perc).absoluteValue < 0.08f })
@ -473,7 +472,7 @@ private fun formatHistoryChart(
}
}
val clusters = diff.asIterable().clusterize(rand, zeroBound = true)
val clusters = diff.asIterable().clusterize(THREAD_LOCAL_RANDOM, zeroBound = true)
for (cluster in clusters) {
val perc: Float

View File

@ -2,15 +2,12 @@ package ru.dbotthepony.mc.otm.core.util
import net.minecraft.util.Mth
import net.minecraft.util.RandomSource
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
import net.minecraft.world.level.levelgen.PositionalRandomFactory
import net.minecraft.world.level.levelgen.RandomSupport
import ru.dbotthepony.kommons.random.GJRAND64Random
import java.lang.StringBuilder
class GJRAND64RandomSource : GJRAND64Random, IRandomSourceGenerator {
private val gaussian = MarsagliaPolarGaussian(this)
constructor() : super(RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed())
constructor(seed: Long) : super(seed)
constructor(seed0: Long, seed1: Long) : super(seed0, seed1)
@ -19,10 +16,6 @@ class GJRAND64RandomSource : GJRAND64Random, IRandomSourceGenerator {
return nextLong().ushr(32).toInt()
}
override fun nextGaussian(): Double {
return gaussian.nextGaussian()
}
override fun fork(): RandomSource {
return GJRAND64RandomSource(nextLong(), nextLong())
}
@ -33,7 +26,6 @@ class GJRAND64RandomSource : GJRAND64Random, IRandomSourceGenerator {
override fun setSeed(seed: Long) {
reinitialize(seed)
gaussian.reset()
}
class Positional(private val seed0: Long, private val seed1: Long) : PositionalRandomFactory {

View File

@ -26,5 +26,7 @@ interface IRandomSourceGenerator : RandomSource, RandomGenerator {
return super.nextDouble()
}
override fun nextGaussian(): Double
override fun nextGaussian(): Double {
return super.nextGaussian()
}
}

View File

@ -198,7 +198,7 @@ object FlywheelMaterials : SimpleJsonResourceReloadListener(GsonBuilder().setPre
).apply(it, ::Entry)
}
fun reloadEvent(event: AddReloadListenerEvent) {
internal fun reloadEvent(event: AddReloadListenerEvent) {
event.addListener(this)
}
@ -227,7 +227,7 @@ object FlywheelMaterials : SimpleJsonResourceReloadListener(GsonBuilder().setPre
}
}
fun onDataPackSync(event: OnDatapackSyncEvent) {
internal fun onDataPackSync(event: OnDatapackSyncEvent) {
if (event.player == null) {
PacketDistributor.sendToAllPlayers(SyncPacket(elements))
} else {
@ -235,7 +235,7 @@ object FlywheelMaterials : SimpleJsonResourceReloadListener(GsonBuilder().setPre
}
}
fun tooltipEvent(event: ItemTooltipEvent) {
internal fun tooltipEvent(event: ItemTooltipEvent) {
if (minecraft.window.isShiftDown) {
val item = event.itemStack.item

View File

@ -7,7 +7,7 @@ import net.minecraft.world.level.storage.loot.LootContext
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.data.get
import ru.dbotthepony.mc.otm.registry.data.MLootItemConditions

View File

@ -5,7 +5,7 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.data.get
import ru.dbotthepony.mc.otm.registry.data.MLootItemConditions

View File

@ -52,7 +52,7 @@ abstract class DecimalProvider : SampledDecimal {
registror.register("uniform") { UniformDecimal }
}
fun register(bus: IEventBus) {
internal fun register(bus: IEventBus) {
bus.addListener(registryHolder::build)
registror.register(bus)
}

View File

@ -19,7 +19,7 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.gameevent.GameEvent
import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.position
import ru.dbotthepony.mc.otm.menu.decorative.MinecartCargoCrateMenu
import ru.dbotthepony.mc.otm.registry.game.MItems
@ -90,7 +90,7 @@ class MinecartCargoCrate(
if (interactingPlayers++ == 0) {
if (!isRemoved) {
level().playSound(null, this, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level().random.nextFloat() * 0.2f)
level().playSound(null, this, MSoundEvents.CARGO_CRATE_OPEN, SoundSource.BLOCKS, 1f, 0.8f + level().otmRandom.nextFloat() * 0.2f)
this.gameEvent(GameEvent.CONTAINER_OPEN, player)
PiglinAi.angerNearbyPiglins(player, true)
}

View File

@ -7,18 +7,17 @@ import net.minecraft.world.item.Items
import net.neoforged.bus.api.SubscribeEvent
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.registry.game.MItems
object WitheredSkeletonSpawnHandler {
@SubscribeEvent
fun onEntityJoin(event: EntityJoinLevelEvent) {
internal fun onEntityJoin(event: EntityJoinLevelEvent) {
val entity = event.entity
if (entity is WitherSkeleton) {
val giveHelmet = event.level.random.nextFloat() < ServerConfig.WITHER_SKELETON_HELMET_CHANCE
val giveSword = event.level.random.nextFloat() < ServerConfig.WITHER_SKELETON_SWORD_CHANCE
val giveHelmet = event.level.otmRandom.nextDouble() < ServerConfig.WITHER_SKELETON_HELMET_CHANCE
val giveSword = event.level.otmRandom.nextDouble() < ServerConfig.WITHER_SKELETON_SWORD_CHANCE
if (giveHelmet) {
if (!entity.hasItemInSlot(EquipmentSlot.HEAD))

View File

@ -21,6 +21,7 @@ import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.config.ItemsConfig
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener
import ru.dbotthepony.mc.otm.registry.MDamageTypes
import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes
@ -184,7 +185,7 @@ class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) {
if (player is ServerPlayer) {
if (!mattery.androidEnergy.item.isEmpty) {
mattery.androidEnergy.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let {
it.extractEnergy((it.maxEnergyStored * level.random.nextFloat() * .2f).roundToInt(), false)
it.extractEnergy((it.maxEnergyStored * level.otmRandom.nextFloat() * .2f).roundToInt(), false)
}
mattery.dropBattery()
@ -194,7 +195,7 @@ class CrudeBatteryItem : BatteryItem(ItemsConfig.Batteries.CRUDE) {
copyStack.count = 1
mattery.androidEnergy.item = copyStack
val extraDamageMult = level.random.nextFloat()
val extraDamageMult = level.otmRandom.nextFloat()
player.hurt(MatteryDamageSource(level.registryAccess().damageType(MDamageTypes.EMP), inflictor = itemStack), 1.5f + extraDamageMult * 3.5f)
val debuffDuration = 100 + (100 * (1f - extraDamageMult)).roundToInt()

View File

@ -106,7 +106,7 @@ class ChestUpgraderItem : MatteryItem(Properties().stacksTo(1)) {
}
companion object {
fun onEntityInteract(event: PlayerInteractEvent.EntityInteract) {
internal fun onEntityInteract(event: PlayerInteractEvent.EntityInteract) {
if (event.target !is MinecartChest) return
val offhand = if (event.entity.getItemInHand(InteractionHand.MAIN_HAND).item is ChestUpgraderItem) {

View File

@ -68,7 +68,7 @@ class PortableCondensationDriveItem(capacity: Int) : Item(Properties().stacksTo(
const val MAX_FILTERS = 4 * 3
private val EMPTY_FILTER = ItemFilter(MAX_FILTERS)
fun onPickupEvent(event: ItemEntityPickupEvent.Pre) {
internal fun onPickupEvent(event: ItemEntityPickupEvent.Pre) {
if (event.itemEntity.owner != null && event.itemEntity.owner != event.player && event.itemEntity.age < 200 || event.itemEntity.item.isEmpty) {
return
}

View File

@ -317,7 +317,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
}
companion object {
fun clientDisconnect(event: ClientPlayerNetworkEvent.LoggingOut) {
internal fun clientDisconnect(event: ClientPlayerNetworkEvent.LoggingOut) {
BuiltInRegistries.ITEM.forEach { if (it is QuantumBatteryItem) it.clientData.clear() }
}
@ -331,7 +331,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
)
}
fun tick(event: ServerTickEvent.Post) {
internal fun tick(event: ServerTickEvent.Post) {
for (ply in event.server.playerList.players) {
val networkedChannels = ObjectOpenHashSet<UUID>(0)

View File

@ -53,7 +53,7 @@ class TritaniumArmorItem(slot: Type) : ArmorItem(MArmorMaterials.TRITANIUM, slot
val TEXTURE_LOCATION_BASE = loc("textures/models/armor/tritanium_armor_base.png")
val TEXTURE_LOCATION_OVERLAY = loc("textures/models/armor/tritanium_armor_overlay.png")
fun onHurt(event: LivingIncomingDamageEvent) {
internal fun onHurt(event: LivingIncomingDamageEvent) {
if (event.source.typeHolder().`is`(DamageTypes.SWEET_BERRY_BUSH) || event.source.msgId == "sweetBerryBush") {
if (
event.entity.getItemBySlot(EquipmentSlot.FEET).let { !it.isEmpty && it.item == MItems.TRITANIUM_BOOTS } &&

View File

@ -13,11 +13,11 @@ import net.minecraft.world.item.*
import net.minecraft.world.item.alchemy.PotionContents
import net.minecraft.world.item.alchemy.Potions
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.isShiftDown
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.getLevelFromXp
import ru.dbotthepony.mc.otm.item.MatteryItem
import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes
@ -81,7 +81,7 @@ class EssenceCapsuleItem(private val digital: Boolean) : MatteryItem(Properties(
} else {
if (level is ServerLevel) {
level.levelEvent(2002, player.blockPosition(), PotionContents.getColor(Potions.WATER))
ExperienceOrb.award(level, player.position(), (exp * (.5 + level.random.nextFloat() * .25)).toInt())
ExperienceOrb.award(level, player.position(), (exp * (.5 + level.otmRandom.nextFloat() * .25)).toInt())
}
}

View File

@ -11,7 +11,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Rarity
import net.minecraft.world.item.UseAnim
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.item.MatteryItem

View File

@ -9,7 +9,7 @@ import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.position
import ru.dbotthepony.mc.otm.entity.BreadMonster
import ru.dbotthepony.mc.otm.item.MatteryItem
@ -39,7 +39,7 @@ class ImperfectBreadItem(properties: Properties) : MatteryItem(properties) {
// roll multiple times so multiple bread monsters can spawn on tick
// and also chance be less biased
for (i in 0 until stack.count.coerceAtMost(16)) {
if (entity.level().random.nextFloat() < 0.001f) {
if (entity.level().otmRandom.nextFloat() < 0.001f) {
val ent = BreadMonster(entity.level())
ent.position = entity.position
entity.level().addFreshEntity(ent)

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.item.consumables
import net.minecraft.ChatFormatting
import net.minecraft.core.component.DataComponentMap
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.Style
import net.minecraft.tags.TagKey
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
@ -18,7 +17,7 @@ import net.minecraft.world.item.UseAnim
import net.minecraft.world.level.Level
import net.minecraft.world.level.gameevent.GameEvent
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent.EntityInteract
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.isShiftDown
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.TranslatableComponent
@ -108,7 +107,7 @@ class NotNormalFood(
}
companion object {
fun onInteract(event: EntityInteract) {
internal fun onInteract(event: EntityInteract) {
val item = event.itemStack.item as? NotNormalFood ?: return
val target = event.target as? LivingEntity ?: return

View File

@ -8,7 +8,7 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.*
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.item.MatteryItem
import ru.dbotthepony.mc.otm.registry.MDamageTypes

View File

@ -10,7 +10,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Rarity
import net.minecraft.world.item.UseAnim
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.item.MatteryItem

View File

@ -15,7 +15,7 @@ import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.UseAnim
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.config.ServerConfig
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.isExplosion

View File

@ -11,7 +11,7 @@ import net.minecraft.world.item.*
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.onceServer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.registry.MDamageTypes

View File

@ -13,8 +13,8 @@ import net.minecraft.world.item.Rarity
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.UseAnim
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.runIfClient

View File

@ -84,7 +84,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1)
itemStack.hurtAndBreak(8, level, player) {}
if (isPrimed(itemStack)) {
itemStack.hurtAndBreak(level.random.nextInt(1, 20), level, player) {}
itemStack.hurtAndBreak(level.otmRandom.nextInt(1, 20), level, player) {}
unprime(itemStack)
val (ex, ey, ez) = Vector.atCenterOf(player.blockPosition())
@ -226,7 +226,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1)
val copy = itemStack.copy()
itemStack.hurtAndBreak(level.random.nextInt(1, 20), attacker, EquipmentSlot.MAINHAND)
itemStack.hurtAndBreak(level.otmRandom.nextInt(1, 20), attacker, EquipmentSlot.MAINHAND)
if (!itemStack.isEmpty && attacker.random.nextDouble() <= ToolsConfig.ExplosiveHammer.FLY_OFF_CHANCE) {
attacker.setItemInHand(hand, ItemStack.EMPTY)
@ -321,7 +321,7 @@ class ExplosiveHammerItem(durability: Int = 512) : Item(Properties().stacksTo(1)
val GUNPOWDER_PREDICATE = Predicate { stack: ItemStack -> stack.`is`(Tags.Items.GUNPOWDERS) }
val IRON_NUGGET_PREDICATE = Predicate { stack: ItemStack -> stack.`is`(Tags.Items.NUGGETS_IRON) }
fun onLeftClickBlock(event: PlayerInteractEvent.LeftClickBlock) {
internal fun onLeftClickBlock(event: PlayerInteractEvent.LeftClickBlock) {
val item = event.itemStack.item
if (item is ExplosiveHammerItem) {

View File

@ -122,7 +122,7 @@ class RedstoneInteractorItem : MatteryItem(Properties().stacksTo(1)) {
return -1
}
fun onUse(event: UseItemOnBlockEvent) {
internal fun onUse(event: UseItemOnBlockEvent) {
if (event.itemStack.item is RedstoneInteractorItem) {
if ((event.itemStack.item as RedstoneInteractorItem).useOn(event.useOnContext).consumesAction())
event.cancelWithResult(ItemInteractionResult.sidedSuccess(event.level.isClientSide()))

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm.item.weapon
import net.minecraft.core.BlockPos
import net.minecraft.core.component.DataComponents
import net.minecraft.tags.BlockTags
import net.minecraft.world.entity.EquipmentSlotGroup
import net.minecraft.world.entity.LivingEntity
@ -26,14 +25,14 @@ import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.capability.energy.getBarColor
import ru.dbotthepony.mc.otm.capability.energy.getBarWidth
import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.math.nextVariance
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.item.MatteryItem
import ru.dbotthepony.mc.otm.item.addSimpleDescription
@ -98,10 +97,10 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE)
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
it.extractEnergy(attacker.level().random.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
it.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
victim.matteryPlayer?.let {
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
it.androidEnergy.extractEnergy(attacker.level().random.nextVariance(ENERGY_ZAP_VARIANCE), false)
it.androidEnergy.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_ZAP_VARIANCE), false)
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
}
}
@ -144,12 +143,12 @@ class EnergySwordItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.RARE)
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
energy.extractEnergyExact(user.level().random.nextVariance(PLANT_POWER_COST_VARIANCE), false)
energy.extractEnergyExact(user.level().otmRandom.nextVariance(PLANT_POWER_COST_VARIANCE), false)
}
if (blockState.`is`(Blocks.COBWEB)) {
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
energy.extractEnergyExact(user.level().random.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
energy.extractEnergyExact(user.level().otmRandom.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
}
}

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm.item.weapon
import net.minecraft.core.BlockPos
import net.minecraft.core.component.DataComponents
import net.minecraft.tags.BlockTags
import net.minecraft.world.entity.EquipmentSlotGroup
import net.minecraft.world.entity.LivingEntity
@ -26,14 +25,14 @@ import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.capability.energy.getBarColor
import ru.dbotthepony.mc.otm.capability.energy.getBarWidth
import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.math.nextVariance
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.item.MatteryItem
import ru.dbotthepony.mc.otm.item.addSimpleDescription
@ -98,10 +97,10 @@ class FallingSunItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.EPIC))
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
it.extractEnergy(attacker.level().random.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
it.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
victim.matteryPlayer?.let {
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
it.androidEnergy.extractEnergy(attacker.level().random.nextVariance(ENERGY_ZAP_VARIANCE), false)
it.androidEnergy.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_ZAP_VARIANCE), false)
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
}
}
@ -144,12 +143,12 @@ class FallingSunItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.EPIC))
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
energy.extractEnergyExact(user.level().random.nextVariance(PLANT_POWER_COST_VARIANCE), false)
energy.extractEnergyExact(user.level().otmRandom.nextVariance(PLANT_POWER_COST_VARIANCE), false)
}
if (blockState.`is`(Blocks.COBWEB)) {
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
energy.extractEnergyExact(user.level().random.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
energy.extractEnergyExact(user.level().otmRandom.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
}
}

View File

@ -114,7 +114,7 @@ abstract class AbstractRegistryAction(
registrar.register("blacklist") { BlacklistAction.Companion }
}
fun register(bus: IEventBus) {
internal fun register(bus: IEventBus) {
registrar.register(bus)
bus.addListener(registryDelegate::build)
}

View File

@ -36,7 +36,7 @@ interface IMatterFunction {
val AT_MOST: IMatterFunction by registrar.register("at_most") { SimpleMatterFunction(Int::coerceAtMost, Double::coerceAtMost, Decimal::coerceAtMost) }
val REPLACE: IMatterFunction by registrar.register("replace") { SimpleMatterFunction({ _, value -> value }, { _, value -> value }, { _, value -> value }) }
fun register(bus: IEventBus) {
internal fun register(bus: IEventBus) {
registrar.register(bus)
bus.addListener(registryDelegate::build)
}

View File

@ -1334,7 +1334,7 @@ object MatterManager {
private val formatMatterAsReadable = BooleanSupplier { if (ClientConfig.Tooltip.ALWAYS_DISPLAY_MATTER_VALUE) minecraft.window.isShiftDown else minecraft.window.isShiftDown && milliTime % 2_000L > 1_000L }
fun tooltipEvent(event: ItemTooltipEvent) {
internal fun tooltipEvent(event: ItemTooltipEvent) {
if (ClientConfig.Tooltip.ALWAYS_DISPLAY_MATTER_VALUE || minecraft.window.isShiftDown) {
val matter = get(event.itemStack, accountForStackSize = false)
@ -1527,12 +1527,12 @@ object MatterManager {
}
}
fun reloadEvent(event: AddReloadListenerEvent) {
internal fun reloadEvent(event: AddReloadListenerEvent) {
event.addListener(Registry)
event.addListener(Resolver)
}
fun initialize(bus: IEventBus) {
internal fun initialize(bus: IEventBus) {
bus.addListener(Resolver.delegate::build)
Resolver.registrar.register(bus)
}
@ -1632,7 +1632,7 @@ object MatterManager {
return 0
}
fun addCommands(event: RegisterCommandsEvent) {
internal fun addCommands(event: RegisterCommandsEvent) {
event.dispatcher.register(
Commands.literal("dump_matter_registry")
.requires { it.hasPermission(Commands.LEVEL_OWNERS) }
@ -1685,7 +1685,7 @@ object MatterManager {
syncRegistry(server.registryAccess(), PacketDistributor::sendToAllPlayers)
}
fun onDataPackSync(event: OnDatapackSyncEvent) {
internal fun onDataPackSync(event: OnDatapackSyncEvent) {
if (!registryIsBuilt)
return
@ -1696,7 +1696,7 @@ object MatterManager {
}
}
fun onServerStarted(event: ServerStartedEvent) {
internal fun onServerStarted(event: ServerStartedEvent) {
check(Resolver.ready) { "Recipe resolver is not ready somehow" }
check(Registry.ready) { "Matter registry is not ready somehow" }
finishUpIfRequiredAndPossible(event.server)

View File

@ -17,7 +17,7 @@ import net.minecraft.world.inventory.Slot
import net.minecraft.world.inventory.TransientCraftingContainer
import net.minecraft.world.item.ItemStack
import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.player.MatteryPlayer
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
import ru.dbotthepony.mc.otm.container.util.slotIterator
import ru.dbotthepony.mc.otm.menu.input.InstantBooleanInput

View File

@ -34,7 +34,7 @@ import ru.dbotthepony.kommons.util.getValue
import ru.dbotthepony.kommons.util.setValue
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.player.matteryPlayer
import ru.dbotthepony.mc.otm.compat.cos.cosmeticArmorSlots
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
import ru.dbotthepony.mc.otm.compat.curios.isCurioSlot
@ -44,6 +44,7 @@ import ru.dbotthepony.mc.otm.container.sortWithIndices
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.collect.ConditionalSet
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.network.MatteryStreamCodec
@ -81,7 +82,7 @@ abstract class MatteryMenu(
val mSynchronizer = SynchableGroup()
val synchronizerRemote = mSynchronizer.Remote()
val player: Player get() = inventory.player
val random: RandomSource = RandomSource.create()
val random = GJRAND64RandomSource()
private val _playerInventorySlots = ArrayList<InventorySlot>()
private val _playerHotbarSlots = ArrayList<InventorySlot>()

Some files were not shown because too many files have changed in this diff Show More