Add 'is_standing_on_blocks' MoLang function

This commit is contained in:
lion
2024-12-27 12:36:04 +00:00
committed by Polymeta
parent 93a368a844
commit 7bbfbf5852
6 changed files with 39 additions and 37 deletions
+3
View File
@@ -1,6 +1,9 @@
# Changelog
## [1.6.1 (Release TBD)](#1-6-1)
### Additions
- Added the `is_standing_on_blocks(depth, blocks...)` MoLang function, which returns whether the specified entity is standing on a specific block or set of blocks. Example usage: `q.is_standing_on_blocks(2, minecraft:sand)`
### Fixes
- Fix Pokédex sometimes crashing when switching forms
- Fix crash related to Tom's Simple Storage and Fossil Machine
@@ -514,6 +514,17 @@ object MoLangFunctions {
.map { it.asMostSpecificMoLangValue() }
.asArrayValue()
}
map.put("is_standing_on_blocks") { params ->
val depth = params.getDouble(0).toInt()
val blocks: MutableSet<Block> = mutableSetOf()
for (blockIndex in 1..<params.params.size) {
val blockString = params.getString(blockIndex)
val block = BuiltInRegistries.BLOCK.get(blockString.asIdentifierDefaultingNamespace("minecraft"))
blocks.add(block)
}
return@put if (entity.isStandingOn(blocks, depth)) DoubleValue.ONE else DoubleValue.ZERO
}
if (entity is PosableEntity) {
map.put("play_animation") { params ->
val animation = params.getString(0)
@@ -54,9 +54,12 @@ class PoseAdapter(
addCondition("isTouchingWater") { entity, expectedValue -> entity.isInWater == expectedValue }
addCondition("isInWaterOrRain") { entity, expectedValue -> entity.isInWaterOrRain == expectedValue }
addCondition("isUnderWater") { entity, expectedValue -> entity.isUnderWater == expectedValue }
// Kept for compatibility
addCondition("isStandingOnRedSand") { entity, expectedValue -> entity.isStandingOnRedSand() == expectedValue }
addCondition("isStandingOnSand") { entity, expectedValue -> entity.isStandingOnSand() == expectedValue }
addCondition("isStandingOnSandOrRedSand") { entity, expectedValue -> entity.isStandingOnSandOrRedSand() == expectedValue }
addCondition("isDusk") { entity, expectedValue -> entity.isDusk() == expectedValue }
conditionsList.addAll(poseConditionReader(json))
@@ -93,4 +96,4 @@ class PoseAdapter(
)
}
}
}
}
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.util
import com.google.common.collect.ImmutableMap
import com.mojang.serialization.Dynamic
import com.mojang.serialization.DynamicOps
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.nbt.NbtOps
@@ -18,6 +17,7 @@ import net.minecraft.nbt.Tag
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
@@ -188,47 +188,32 @@ fun Entity.setPositionSafely(pos: Vec3): Boolean {
}
}
fun Entity.isStandingOnSandOrRedSand(): Boolean {
val sandDepth = 2 // Define the depth you want to check
for (a in 1..sandDepth) {
val sandBlockState = this.level().getBlockState(blockPosition().below(a))
val sandBlock = sandBlockState.block
if (sandBlock == Blocks.SAND && !sandBlockState.isAir && sandBlockState.isCollisionShapeFullBlock(this.level(), blockPosition().below(a))) {
return true
}
if (sandBlock == Blocks.RED_SAND && !sandBlockState.isAir && sandBlockState.isCollisionShapeFullBlock(this.level(), blockPosition().below(a))) {
return true
}
}
return false
}
fun Entity.isDusk(): Boolean {
val time = level().dayTime % 24000
return time in 12000..13000
}
fun Entity.isStandingOnSand(): Boolean {
val sandDepth = 2 // Define the depth you want to check
for (a in 1..sandDepth) {
val sandBlockState = this.level().getBlockState(blockPosition().below(a))
val sandBlock = sandBlockState.block
if (sandBlock == Blocks.SAND && !sandBlockState.isAir && sandBlockState.isCollisionShapeFullBlock(this.level(), blockPosition().below(a))) {
return true
}
}
return false
return isStandingOn(setOf(Blocks.SAND))
}
fun Entity.isStandingOnRedSand(): Boolean {
val redSandDepth = 2 // Define the depth you want to check
for (i in 1..redSandDepth) {
val redSandBlockState = this.level().getBlockState(blockPosition().below(i))
val redSandBlock = redSandBlockState.block
if (redSandBlock == Blocks.RED_SAND && !redSandBlockState.isAir && redSandBlockState.isCollisionShapeFullBlock(this.level(), blockPosition().below(i))) {
return true
}
return isStandingOn(setOf(Blocks.RED_SAND))
}
fun Entity.isStandingOnSandOrRedSand(): Boolean {
return isStandingOn(setOf(Blocks.SAND, Blocks.RED_SAND))
}
fun Entity.isStandingOn(blocks: Set<Block>, depth: Int = 2): Boolean {
for (currentDepth in 1..depth) {
val bellowBlockPos = blockPosition().below(currentDepth)
val blockState = level().getBlockState(bellowBlockPos)
if (blockState.isAir || !blockState.isCollisionShapeFullBlock(level(), bellowBlockPos)) continue
if (blocks.contains(blockState.block)) return true
}
return false
}
@@ -46,7 +46,7 @@
},
"sand-sleep": {
"poseTypes": ["SLEEP"],
"isStandingOnSandOrRedSand": true,
"condition": "q.is_standing_on_blocks(2, 'minecraft:sand', 'minecraft:red_sand')",
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
@@ -54,7 +54,7 @@
},
"sleep": {
"poseTypes": ["SLEEP"],
"isStandingOnSandOrRedSand": false,
"condition": "!q.is_standing_on_blocks(2, 'minecraft:sand', 'minecraft:red_sand')",
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
@@ -48,7 +48,7 @@
},
"battle-sleep": {
"poseTypes": ["SLEEP"],
"isStandingOnSandOrRedSand": true,
"condition": "q.is_standing_on_blocks(2, 'minecraft:sand', 'minecraft:red_sand')",
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
@@ -56,7 +56,7 @@
},
"sleep": {
"poseTypes": ["SLEEP"],
"isStandingOnSandOrRedSand": false,
"condition": "!q.is_standing_on_blocks(2, 'minecraft:sand', 'minecraft:red_sand')",
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},