Added some hooks to cover system, fixed rendering covers when breaking blocks

This commit is contained in:
bdew committed 2015-08-25 15:52:45 +03:00
1 parent 6c59b25e2c
commit 3aef519c25
3 files changed
+127 -26

No files matched your search

+66 -17
View File
@@ -11,10 +11,11 @@ package net.bdew.lib.covers
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.bdew.lib.Misc
import net.bdew.lib.block.HasTE
import net.bdew.lib.block.{BlockRef, HasTE}
import net.bdew.lib.items.ItemUtils
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
import net.minecraft.item.ItemStack
import net.minecraft.util.IIcon
import net.minecraft.world.{IBlockAccess, World}
import net.minecraftforge.common.util.ForgeDirection
@@ -23,53 +24,101 @@ trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
@SideOnly(Side.CLIENT)
override def getRenderType = CoverRenderer.id
private def getCoverItem(w: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection): Option[(ItemCover, ItemStack, TileCoverable)] = {
val te = getTE(w, x, y, z)
for {
coverStack <- Option(te.covers(side).value)
coverItemMaybe <- Option(coverStack.getItem)
coverItem <- Misc.asInstanceOpt(coverItemMaybe, classOf[ItemCover])
} yield (coverItem, coverStack, te)
}
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, face: Int, xOffs: Float, yOffs: Float, zOffs: Float): Boolean = {
val te = getTE(world, x, y, z)
val side = Misc.forgeDirection(face)
// Shift+RightClick with empty hand should remove cover
if (player.getCurrentEquippedItem == null && player.isSneaking) {
for (cover <- Option(te.covers(side).value)) {
for {
cover <- Option(te.covers(side).value)
coverItem <- Misc.asInstanceOpt(cover.getItem, classOf[ItemCover])
} {
if (!world.isRemote) {
te.covers(side) := null
te.onCoversChanged()
ItemUtils.dropItemToPlayer(world, player, cover)
coverChanged(world, x, y, z, side)
ItemUtils.dropItemToPlayer(world, player, coverItem.onRemove(cover))
}
return true
}
}
// If held item is cover - try to install it
for {
activeStack <- Option(player.getCurrentEquippedItem)
activeItem <- Option(activeStack.getItem)
coverItem <- Misc.asInstanceOpt(activeItem, classOf[ItemCover])
if te.isValidCover(side, activeStack) && coverItem.isValidTile(te, activeStack)
} {
if (!world.isRemote) {
for (cover <- Option(te.covers(side).value))
ItemUtils.throwItemAt(world, te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ, cover.copy())
if (!world.isRemote && player.isInstanceOf[EntityPlayerMP]) {
for {
oldCover <- Option(te.covers(side).value)
oldItem <- Misc.asInstanceOpt(oldCover.getItem, classOf[ItemCover])
} {
ItemUtils.throwItemAt(world, te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ, oldItem.onRemove(oldCover))
}
te.covers(side) := activeStack.splitStack(1)
te.covers(side) := coverItem.onInstall(te, side, activeStack.splitStack(1), player.asInstanceOf[EntityPlayerMP])
if (activeStack.stackSize <= 0)
player.inventory.setInventorySlotContents(player.inventory.currentItem, null)
if (activeStack.stackSize <= 0) player.inventory.setInventorySlotContents(player.inventory.currentItem, null)
te.onCoversChanged()
coverChanged(world, x, y, z, side)
}
return true
}
// If has cover - let it handle the click
for ((item, stack, te) <- getCoverItem(world, x, y, z, side)) {
if (item.clickCover(te, side, stack, player)) return true
}
super.onBlockActivated(world, x, y, z, player, face, xOffs, yOffs, zOffs)
}
override def canProvidePower = true
override def isProvidingWeakPower(w: IBlockAccess, x: Int, y: Int, z: Int, side: Int): Int = {
val direction = Misc.forgeDirection(side).getOpposite
for ((item, stack, te) <- getCoverItem(w, x, y, z, direction)) {
if (item.isEmittingSignal(te, direction, stack)) return 15
}
0
}
def coverChanged(w: World, x: Int, y: Int, z: Int, side: ForgeDirection): Unit = {
val pos = BlockRef(x, y, z).neighbour(side)
w.notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, pos.block(w).orNull)
}
def getCoverIcon(w: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection): Option[IIcon] =
for {
coverStack <- Option(getTE(w, x, y, z).covers(side).value)
coverItemMaybe <- Option(coverStack.getItem)
coverItem <- Misc.asInstanceOpt(coverItemMaybe, classOf[ItemCover])
} yield coverItem.getCoverIcon(coverStack)
for ((item, stack, te) <- getCoverItem(w, x, y, z, side))
yield item.getCoverIcon(te, side, stack)
override def breakBlock(world: World, x: Int, y: Int, z: Int, block: Block, meta: Int) {
if (!world.isRemote)
for ((dir, covOpt) <- getTE(world, x, y, z).covers; cover <- Option(covOpt.value))
ItemUtils.throwItemAt(world, x, y, z, cover)
if (!world.isRemote) {
val te = getTE(world, x, y, z)
for {
(dir, covOpt) <- te.covers
cover <- Option(covOpt.value)
item <- Misc.asInstanceOpt(cover.getItem, classOf[ItemCover])
} {
te.covers(dir) := null
ItemUtils.throwItemAt(world, x, y, z, item.onRemove(cover))
coverChanged(world, x, y, z, dir)
}
}
super.breakBlock(world, x, y, z, block, meta)
}
}
+7 -6
View File
@@ -23,12 +23,13 @@ object CoverRenderer extends BaseBlockRenderHandler {
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks) = {
renderer.renderStandardBlock(block, x, y, z)
for {
blockCov <- Misc.asInstanceOpt(block, classOf[BlockCoverable[_]])
face <- ForgeDirection.VALID_DIRECTIONS
icon <- blockCov.getCoverIcon(world, x, y, z, face)
if block.shouldSideBeRendered(world, x + face.offsetX, y + face.offsetY, z + face.offsetZ, face.ordinal())
} ConnectedHelper.draw(face, 8).doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
if (!renderer.hasOverrideBlockTexture)
for {
blockCov <- Misc.asInstanceOpt(block, classOf[BlockCoverable[_]])
face <- ForgeDirection.VALID_DIRECTIONS
icon <- blockCov.getCoverIcon(world, x, y, z, face)
if block.shouldSideBeRendered(world, x + face.offsetX, y + face.offsetY, z + face.offsetZ, face.ordinal())
} ConnectedHelper.draw(face, 8).doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
true
}
}
+54 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013 - 2014
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,23 +9,74 @@
package net.bdew.lib.covers
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.util.IIcon
import net.minecraftforge.common.util.ForgeDirection
trait ItemCover extends Item {
/**
* @return true if tickCover should be called
*/
def isCoverTicking: Boolean
/**
* @param te Host TileEntity
* @param side Side the cover is installed on
* @param cover Cover ItemStack
* @return Icon to render, MUST be on terrain sprite sheet (0), not item!
*/
def getCoverIcon(stack: ItemStack): IIcon
def getCoverIcon(te: TileCoverable, side: ForgeDirection, cover: ItemStack): IIcon
/**
* Perform tick, called on server only
* @param te Host TileEntity
* @param side Side the cover is installed on
* @param cover Cover ItemStack
*/
def tickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack)
def tickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack): Unit = {}
/**
* Checks if this cover can be installed on a specific TE
* @param te Potential host TileEntity
* @param cover Cover ItemStack
* @return true if can be installed
*/
def isValidTile(te: TileCoverable, cover: ItemStack): Boolean
/**
* Handle click on covered side - called on both client and server
* @param te Host TileEntity
* @param side Side the cover is installed on
* @param cover Cover ItemStack
* @param player Player clicking the cover
* @return true if click was handled by cover
*/
def clickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack, player: EntityPlayer): Boolean = false
/**
* Check if cover is emitting RS signal
* @param te Host TileEntity
* @param side Side the cover is installed on
* @param cover Cover ItemStack
* @return true if cover is emitting RS signal
*/
def isEmittingSignal(te: TileCoverable, side: ForgeDirection, cover: ItemStack): Boolean = false
/**
* Called when cover is installed on a block - called only on server
* @param te Host TileEntity
* @param side Side the cover is installed on
* @param cover Cover ItemStack - do not modify!
* @param player Player entity doing the installation
* @return cover ItemStack - copy if modified
*/
def onInstall(te:TileCoverable, side: ForgeDirection, cover: ItemStack, player: EntityPlayerMP): ItemStack = cover
/**
* Called when cover is removed from block or block is destroyed - called only on server
* @param cover Cover ItemStack - do not modify!
* @return cover ItemStack - copy if modified
*/
def onRemove(cover: ItemStack): ItemStack = cover
}