Skip to content

Commit

Permalink
嘎嘎多新东西
Browse files Browse the repository at this point in the history
新内容
1. 添加熔炉防火设备(WIP)
2. 添加火灾检测器
3. 添加3种不同的灭火器
4. 添加抑燃炸弹
5. 添加喷淋头

调整内容
1. 调整灭火器物品贴图和其他属性
2. 修复爆燃粒子效果
3. 十万火急不再能与冰霜行者共存
4. 调整灭火合成
  • Loading branch information
Taskeren committed May 8, 2022
1 parent 1015f24 commit 3a17f03
Show file tree
Hide file tree
Showing 35 changed files with 1,163 additions and 111 deletions.
2 changes: 1 addition & 1 deletion RawAssets/fire_extinguisher.bbmodel

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ java.toolchain.languageVersion = JavaLanguageVersion.of(17)
minecraft {
mappings channel: "parchment", version: "2022.03.13-1.18.2"

accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')

runs {
client {
workingDirectory project.file("run_client")
Expand Down Expand Up @@ -64,6 +66,8 @@ sourceSets.main.resources {
}

repositories {
maven { url = "https://files.minecraftforge.net/maven" }
maven { url = "https://maven.parchmentmc.org" }
maven { url "https://cursemaven.com"; content {includeGroup("curse.maven") } }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ public abstract class MixinFurnaceTileEntity {

@Inject(method = "serverTick", at = @At("HEAD"))
private static void serverTick(Level pLevel, BlockPos pPos, BlockState pState, AbstractFurnaceBlockEntity pBlockEntity, CallbackInfo ci) {
var mixinFurnaceEntity = (MixinFurnaceTileEntity) (Object) pBlockEntity;
if(pBlockEntity instanceof FurnaceBlockEntity) {
var isLit = ((MixinFurnaceTileEntity)(Object) pBlockEntity).isLit();
var isLit = mixinFurnaceEntity.isLit();
if(isLit) {
if(RANDOM.nextInt(100) > 98) {
var blockPosToFire = getAnyBlockPosCanFire(pLevel, pPos);
Expand Down
65 changes: 65 additions & 0 deletions src/main/kotlin/restricted/fpe/FPEConst.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package restricted.fpe

import net.minecraft.core.Direction
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.item.*
import net.minecraft.world.item.enchantment.EnchantmentCategory
import net.minecraft.world.level.block.SoundType
import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.material.Material

private typealias ItemProperties = Item.Properties
private typealias BlockProperties = BlockBehaviour.Properties

object FPEConst {

object BlockConst {

// BlockBehavior.Properties

val FireHydrantProp: BlockProperties =
BlockProperties.of(Material.HEAVY_METAL).strength(5.0F, 1200.0F).sound(SoundType.ANVIL).noOcclusion()

val FireExtinguishingBombProp: BlockProperties =
BlockProperties.of(Material.EXPLOSIVE).instabreak().sound(SoundType.GRASS)

val FireDetectorProp: BlockProperties =
BlockProperties.of(Material.WOOL).strength(0.8F).sound(SoundType.WOOL).noOcclusion().lightLevel { 3 }

val FireSprinklerProp: BlockProperties =
BlockProperties.of(Material.WOOL).strength(0.8F).sound(SoundType.WOOL).noOcclusion().lightLevel { 3 }

// Property for BlockState

val VERTICAL_FACING: EnumProperty<Direction> =
EnumProperty.create("facing", Direction::class.java, Direction.UP, Direction.DOWN)

}

object ItemConst {

// Item.Properties

val DefaultItemProp: ItemProperties =
Item.Properties().tab(FPE.Tabs.Default)

val DefaultNonStackableItemProp: ItemProperties =
Item.Properties().stacksTo(1).tab(FPE.Tabs.Default)

val FireExtinguisherProp: ItemProperties =
Item.Properties().rarity(Rarity.UNCOMMON).tab(FPE.Tabs.Default).stacksTo(1).durability(15000)
}

object DamageSourceConst {

val SpreadingFire = DamageSource("spreading_fire")

val Extinguish = DamageSource("extinguish")
}

object EnchantCategory {
val BowAndCrossbowCategory: EnchantmentCategory = EnchantmentCategory.create("bow_and_crossbow") { it is BowItem || it is CrossbowItem }
}

}
32 changes: 23 additions & 9 deletions src/main/kotlin/restricted/fpe/FPEKtExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@ import net.minecraft.world.level.material.Material
import net.minecraft.world.phys.Vec3
import net.minecraftforge.registries.ForgeRegistryEntry
import net.minecraftforge.registries.IForgeRegistryEntry
import restricted.fpe.FPEConst.ItemConst.DefaultItemProp

internal typealias MinecraftItems = net.minecraft.world.item.Items
internal typealias MinecraftItems = Items
internal typealias MinecraftBlocks = net.minecraft.world.level.block.Blocks

internal val defaultItemProp = Item.Properties().tab(FPE.Tabs.Default)
internal val defaultSingleItemProp = Item.Properties().stacksTo(1).tab(FPE.Tabs.Default)

internal fun Block.generateBlockItem(properties: Item.Properties = defaultItemProp): BlockItem =
internal fun Block.generateBlockItem(properties: Item.Properties = DefaultItemProp): BlockItem =
BlockItem(this, properties)

internal fun buildItem(itemProp: Item.Properties = defaultItemProp): Item = Item(itemProp)
internal fun buildItem(itemProp: Item.Properties = DefaultItemProp): Item = Item(itemProp)
internal fun buildItem(block: Item.Properties.() -> Unit): Item = buildItem(Item.Properties().apply(block))

internal val <V : IForgeRegistryEntry<V>> ForgeRegistryEntry<V>.registryPath get() = registryName?.path ?: error("")
Expand Down Expand Up @@ -55,8 +53,7 @@ internal fun boundingBoxOfCenter(center: BlockPos, xOff: Int, yOff: Int = xOff,

internal fun BoundingBox.forEach(block: (BlockPos) -> Unit) = BlockPos.betweenClosedStream(this).forEach(block)

internal fun Level.addParticle(particleOptions: ParticleOptions, loc: Vec3, speedX: Double, speedY: Double, speedZ: Double) =
addParticle(particleOptions, loc.x, loc.y, loc.z, speedX, speedY, speedZ)
internal val BoundingBox.AABB get() = net.minecraft.world.phys.AABB.of(this)

internal fun buildSetBlockFlag(
updateBlock: Boolean = false,
Expand Down Expand Up @@ -94,4 +91,21 @@ internal fun <R> Level.runOnRemote(block: ServerLevel.() -> R): R? {
} else {
null
}
}
}

internal fun <R> Level.letOnRemote(block: (ServerLevel) -> R): R? {
return if(this is ServerLevel) {
block(this)
} else {
null
}
}

internal fun ServerLevel.sendParticles(particleOptions: ParticleOptions, pos: Vec3, count: Int, speed: Double, offset: Vec3 = Vec3.ZERO) =
sendParticles(particleOptions, pos.x, pos.y, pos.z, count, offset.x, offset.y, offset.z, speed)

internal fun buildCompoundTag(block: CompoundTag.() -> Unit) = CompoundTag().apply(block)

internal inline fun <reified T: Enum<T>> enumValueOrNull(name: String) = enumValues<T>().find { it.name == name }

infix fun Int.ifZero(nonZeroValue: Int): Int = if(this == 0) { nonZeroValue } else { this }
70 changes: 37 additions & 33 deletions src/main/kotlin/restricted/fpe/FireProtectEquipment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,28 @@

package restricted.fpe

import net.minecraft.core.particles.ParticleTypes
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.effect.MobEffect
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.*
import net.minecraft.world.item.enchantment.Enchantment
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.ForgeRegistries
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import restricted.fpe.block.FireHydrantBlock
import restricted.fpe.block.*
import restricted.fpe.block.entity.FireDetectorBlockEntity
import restricted.fpe.block.entity.FireSprinklerBlockEntity
import restricted.fpe.enchant.FireWalkerEnchant
import restricted.fpe.enchant.SpreadingFireEnchant
import restricted.fpe.extinguish.ExtinguishContext
import restricted.fpe.extinguish.ExtinguishRecipe
import restricted.fpe.extinguish.ExtinguishRecipe.MiniBlockState.Builder.Companion.buildMiniState
import restricted.fpe.item.FireExtinguisherItem
import restricted.fpe.item.FireItem
import restricted.fpe.extinguish.*
import restricted.fpe.item.*
import restricted.fpe.potion.SpreadingFireEffect
import thedarkcolour.kotlinforforge.forge.*
import kotlin.math.log

const val ModId = "fire_protection_equipment"

Expand All @@ -38,6 +35,7 @@ object FPE {
init {
Enchants.registry.register(MOD_BUS)
MobEffects.registry.register(MOD_BUS)
BlockEntityTypes.registry.register(MOD_BUS)
Blocks.registry.register(MOD_BUS)
Items.registry.register(MOD_BUS)

Expand All @@ -46,7 +44,7 @@ object FPE {
serverTarget = { MOD_BUS.addListener(::serverSetup) }
)

registerFireRecipes()
BuiltInRecipes.register()
}

private fun clientSetup(e: FMLClientSetupEvent) {
Expand All @@ -57,29 +55,13 @@ object FPE {
private fun serverSetup(e: FMLDedicatedServerSetupEvent) {
}

private fun registerFireRecipes() {
logger.info("Registering Fire Recipes")

ExtinguishRecipe.register(MinecraftBlocks.FIRE.buildMiniState()) { ctx, _, pos ->
ctx.world.setBlock(pos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(), buildSetBlockFlag(updateBlock = true, sendToClient = true))
ctx.world.addParticle(ParticleTypes.SMOKE, pos.vec3, 0.0, 0.0, 0.0)
println("World = ${ctx.world is ServerLevel}")
ctx.world.runOnRemote {
val v3 = pos.vec3
sendParticles(ParticleTypes.CLOUD, v3.x, v3.y, v3.z, (1..20).random(), 0.0, 0.0, 0.0, 0.2)
}
}

logger.info("End register")
ExtinguishRecipe.recipes.cellSet().forEach { (state, type, func) ->
logger.info("$state & $type => $func")
}// TODO: Removal
}

object Blocks {
internal val registry: DeferredRegister<Block> = DeferredRegister.create(ForgeRegistries.BLOCKS, ModId)

val FireHydrant by registry.registerObject("fire_hydrant") { FireHydrantBlock }
val FireExtinguishingBomb by registry.registerObject("fire_extinguishing_bomb") { FireExtinguishingBombBlock }
val FireDetector by registry.registerObject("fire_detector") { FireDetectorBlock }
val FireSprinkler by registry.registerObject("fire_sprinkler") { FireSprinklerBlock }
}

object Items {
Expand All @@ -90,8 +72,14 @@ object FPE {

val FireHydrant by registry.registerObject("fire_hydrant") { Blocks.FireHydrant.generateBlockItem() }
val BrokenFireHydrant by registry.registerObject("broken_fire_hydrant") { buildItem() }
val FireExtinguishingBomb by registry.registerObject("fire_extinguishing_bomb") { Blocks.FireExtinguishingBomb.generateBlockItem() }
val FireDetector by registry.registerObject("fire_detector") { Blocks.FireDetector.generateBlockItem() }
val FireSprinkler by registry.registerObject("fire_sprinkler") { Blocks.FireSprinkler.generateBlockItem() }

val FireExtinguisher by registry.registerObject("fire_extinguisher") { FireExtinguisherItem }

val FurnaceFireProtectionDevice by registry.registerObject("furnace_fire_protection_device") { FurnaceFireProtectionDeviceItem }

}

object Tabs {
Expand All @@ -115,13 +103,29 @@ object FPE {
val SpreadingFire by registry.registerObject("spreading_fire") { SpreadingFireEffect }
}

@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
object BlockEntityTypes {
internal val registry: DeferredRegister<BlockEntityType<*>> = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITIES, ModId)

val FireDetector: BlockEntityType<FireDetectorBlockEntity> by registry.registerObject("fire_detector") { BlockEntityType.Builder.of(::FireDetectorBlockEntity, Blocks.FireDetector).build(null) }
val FireSprinkler: BlockEntityType<FireSprinklerBlockEntity> by registry.registerObject("fire_sprinkler") { BlockEntityType.Builder.of(::FireSprinklerBlockEntity, Blocks.FireSprinkler).build(null) }
}

fun extinguishFire(context: ExtinguishContext) {
val extinType = context.type
context.boundingBox.forEach {
val state = context.world.getBlockState(it)
val func = ExtinguishRecipe[state, context.type]
val state = context.level.getBlockState(it)
val func = ExtinguishRecipe[state, extinType]
if(func != null) {
func(context, state, it)
println("$state & ${context.type.name} = $func") // TODO: Removal
logger.debug("Executed the ExtinguishRecipe for $state with type $extinType")
}
}
context.level.getEntitiesOfClass(Entity::class.java, context.boundingBox.AABB) { true }.forEach {
val func = ExtinguishRecipe.getForEntity(it.type, extinType)
if(func != null) {
func(context, it)
logger.debug("Executed the Entity ExtinguishRecipe for $it with type $extinType")
}
}
}
Expand Down
96 changes: 96 additions & 0 deletions src/main/kotlin/restricted/fpe/block/FireDetectorBlock.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package restricted.fpe.block

import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.tags.BlockTags
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.entity.*
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
import restricted.fpe.*
import restricted.fpe.FPEConst.BlockConst.VERTICAL_FACING
import restricted.fpe.block.entity.FireDetectorBlockEntity

@Suppress("OVERRIDE_DEPRECATION")
object FireDetectorBlock : BaseEntityBlock(FPEConst.BlockConst.FireDetectorProp) {

private val bottomShape = box(5.0, 0.0, 5.0, 11.0, 2.0, 11.0)
private val topShape = box(5.0, 14.0, 5.0, 11.0, 16.0, 11.0)

init {
registerDefaultState(
this.stateDefinition.any().setValue(VERTICAL_FACING, Direction.UP)
)
}

fun hasFireAround(level: Level, blockPos: BlockPos): Boolean {
return level.getBlockStates(boundingBoxOfCenter(blockPos.below(2), 3).AABB).anyMatch {
it.`is`(BlockTags.FIRE)
}
}

override fun createBlockStateDefinition(pBuilder: StateDefinition.Builder<Block, BlockState>) {
pBuilder.add(VERTICAL_FACING)
}

@Suppress("UNUSED_PARAMETER")
fun onTick(level: Level, pos: BlockPos, state: BlockState, blockEntity: FireDetectorBlockEntity) {
val hasFire = hasFireAround(level, pos)
if(hasFire != blockEntity.fireDetected) {
blockEntity.fireDetected = hasFire
level.updateNeighborsAt(pos, this)
}
}

override fun getRenderShape(pState: BlockState): RenderShape {
return RenderShape.MODEL
}

override fun getStateForPlacement(pContext: BlockPlaceContext): BlockState? {
val direction = if(pContext.clickedFace == Direction.UP) Direction.UP else Direction.DOWN
return defaultBlockState().setValue(VERTICAL_FACING, direction)
}

override fun getShape(
pState: BlockState,
pLevel: BlockGetter,
pPos: BlockPos,
pContext: CollisionContext
): VoxelShape {
return if(pState.getValue(VERTICAL_FACING) == Direction.UP) {
bottomShape
} else {
topShape
}
}

override fun isSignalSource(state: BlockState): Boolean {
return true
}

override fun getSignal(state: BlockState, level: BlockGetter, pos: BlockPos, pDirection: Direction): Int {
val blockEntity = level.getBlockEntity(pos, FPE.BlockEntityTypes.FireDetector)
return if(blockEntity.isPresent && blockEntity.get().fireDetected) {
15
} else {
0
}
}

override fun newBlockEntity(pPos: BlockPos, pState: BlockState): BlockEntity {
return FireDetectorBlockEntity(pPos, pState)
}

override fun <T : BlockEntity?> getTicker(
pLevel: Level,
pState: BlockState,
pBlockEntityType: BlockEntityType<T>
): BlockEntityTicker<T>? {
return createTickerHelper(pBlockEntityType, FPE.BlockEntityTypes.FireDetector, ::onTick)
}
}
Loading

0 comments on commit 3a17f03

Please sign in to comment.