mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 17:28:52 -04:00
Scratch that and let's do it again. Might silence the voices in my head (aka @Vexatos).
Changed robot upgrade rendering to allow being picky. A bit more overhead, but hey, what's a few sets among friends?
This commit is contained in:
parent
fda54f2f6f
commit
1528a6ee24
@ -6,6 +6,8 @@ import li.cil.oc.api.event.RobotRenderEvent;
|
|||||||
import li.cil.oc.api.internal.Robot;
|
import li.cil.oc.api.internal.Robot;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface can be implemented by items to allow custom rendering of
|
* This interface can be implemented by items to allow custom rendering of
|
||||||
* upgrades installed in robots.
|
* upgrades installed in robots.
|
||||||
@ -19,38 +21,32 @@ import net.minecraft.item.ItemStack;
|
|||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public interface UpgradeRenderer {
|
public interface UpgradeRenderer {
|
||||||
/**
|
/**
|
||||||
* The priority with which to render this upgrade.
|
* Returns which mount point this renderer wants to render the specified
|
||||||
|
* upgrade in.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Upgrades with a higher priority are preferred for rendering over other
|
* This method is used to determine which upgrade is rendered where, and is
|
||||||
* upgrades. Upgrades with higher priorities will be rendered in the top
|
* called for every installed, renderable upgrade. The available mount
|
||||||
* slots, i.e. the assigned slot order is top then bottom.
|
* point names are defined in {@link MountPointName}, with the two special
|
||||||
|
* values <tt>None</tt> and <tt>Any</tt>.
|
||||||
* <p/>
|
* <p/>
|
||||||
* You usually won't need the robot parameter, but in case you <em>do</em>
|
* <tt>None</tt> means that the upgrade should not be rendered at all. This
|
||||||
* need some contextual information, this should provide you with anything
|
* can be the case when there is no slot remaining that the upgrade may be
|
||||||
* you could need.
|
* rendered in. Returning <tt>null</tt> is equivalent to returning <tt>None</tt>.
|
||||||
|
* <p/>
|
||||||
|
* <tt>Any</tt> means that the upgrade doesn't really care where it's being
|
||||||
|
* rendered. Mount points not assigned by another upgrade preferring to be
|
||||||
|
* rendered in it will be assigned to such upgrades in the order they are
|
||||||
|
* installed in the robot.
|
||||||
|
* <p/>
|
||||||
|
* Returning a mount point not in the list of available mount points will
|
||||||
|
* be equivalent to returning <tt>None</tt>.
|
||||||
*
|
*
|
||||||
* @param stack the item stack of the upgrade to render.
|
* @param stack the item stack of the upgrade to render.
|
||||||
* @param robot the robot the upgrade is rendered on.
|
* @param robot the robot the upgrade is rendered on.
|
||||||
* @return the priority with which to render the upgrade.
|
* @param availableMountPoints the mount points available for rendering in.
|
||||||
|
* @return the mount point to reserve for the upgrade.
|
||||||
*/
|
*/
|
||||||
int priority(ItemStack stack, Robot robot);
|
String computePreferredMountPoint(ItemStack stack, Robot robot, Set<String> availableMountPoints);
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the upgrade can be rendered in the specified mount point.
|
|
||||||
* <p/>
|
|
||||||
* This is used to determine whether an upgrade can be rendered in a
|
|
||||||
* specific mount point, or not. Note that if the upgrade refuses to
|
|
||||||
* be rendered in the offered mount point, it will not be rendered at all,
|
|
||||||
* i.e. it will not be offered another mount point. To give the upgrade
|
|
||||||
* a better chance to get a usable mount point, specify an appropriate
|
|
||||||
* priority via {@link #priority}.
|
|
||||||
*
|
|
||||||
* @param stack the item stack of the upgrade to render.
|
|
||||||
* @param mountPoint the mount-point to render the upgrade at.
|
|
||||||
* @param robot the robot the upgrade is rendered on.
|
|
||||||
* @return whether the upgrade can be rendered in the specified mount point.
|
|
||||||
*/
|
|
||||||
boolean canRender(ItemStack stack, RobotRenderEvent.MountPoint mountPoint, Robot robot);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the specified upgrade on a robot.
|
* Render the specified upgrade on a robot.
|
||||||
@ -63,7 +59,8 @@ public interface UpgradeRenderer {
|
|||||||
* relative to.
|
* relative to.
|
||||||
* <p/>
|
* <p/>
|
||||||
* If the stack cannot be rendered, the renderer should indicate so in
|
* If the stack cannot be rendered, the renderer should indicate so in
|
||||||
* {@link #canRender}, otherwise it will still consume a mount point.
|
* {@link #computePreferredMountPoint}, otherwise it will still consume a mount
|
||||||
|
* point.
|
||||||
* <p/>
|
* <p/>
|
||||||
* You usually won't need the robot parameter, but in case you <em>do</em>
|
* You usually won't need the robot parameter, but in case you <em>do</em>
|
||||||
* need some contextual information, this should provide you with anything
|
* need some contextual information, this should provide you with anything
|
||||||
@ -75,4 +72,23 @@ public interface UpgradeRenderer {
|
|||||||
* @param pt partial tick time, e.g. for animations.
|
* @param pt partial tick time, e.g. for animations.
|
||||||
*/
|
*/
|
||||||
void render(ItemStack stack, RobotRenderEvent.MountPoint mountPoint, Robot robot, float pt);
|
void render(ItemStack stack, RobotRenderEvent.MountPoint mountPoint, Robot robot, float pt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mount point names for {@link #computePreferredMountPoint}.
|
||||||
|
*/
|
||||||
|
final class MountPointName {
|
||||||
|
public static final String None = "none";
|
||||||
|
public static final String Any = "any";
|
||||||
|
|
||||||
|
public static final String TopLeft = "top_left";
|
||||||
|
public static final String TopRight = "top_right";
|
||||||
|
public static final String TopBack = "top_back";
|
||||||
|
public static final String BottomLeft = "bottom_left";
|
||||||
|
public static final String BottomRight = "bottom_right";
|
||||||
|
public static final String BottomBack = "bottom_back";
|
||||||
|
public static final String BottomFront = "bottom_front";
|
||||||
|
|
||||||
|
private MountPointName() {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package li.cil.oc.client.renderer.item
|
|||||||
|
|
||||||
import li.cil.oc.Constants
|
import li.cil.oc.Constants
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.api.driver.item.UpgradeRenderer.MountPointName
|
||||||
import li.cil.oc.api.event.RobotRenderEvent.MountPoint
|
import li.cil.oc.api.event.RobotRenderEvent.MountPoint
|
||||||
import li.cil.oc.client.Textures
|
import li.cil.oc.client.Textures
|
||||||
import li.cil.oc.integration.opencomputers.Item
|
import li.cil.oc.integration.opencomputers.Item
|
||||||
@ -16,12 +17,15 @@ object UpgradeRenderer {
|
|||||||
lazy val generatorUpgrade = api.Items.get(Constants.ItemName.GeneratorUpgrade)
|
lazy val generatorUpgrade = api.Items.get(Constants.ItemName.GeneratorUpgrade)
|
||||||
lazy val inventoryUpgrade = api.Items.get(Constants.ItemName.InventoryUpgrade)
|
lazy val inventoryUpgrade = api.Items.get(Constants.ItemName.InventoryUpgrade)
|
||||||
|
|
||||||
def priority(stack: ItemStack): Int = {
|
def preferredMountPoint(stack: ItemStack, availableMountPoints: java.util.Set[String]): String = {
|
||||||
val descriptor = api.Items.get(stack)
|
val descriptor = api.Items.get(stack)
|
||||||
|
|
||||||
if (descriptor == craftingUpgrade) 5
|
if (descriptor == craftingUpgrade || descriptor == generatorUpgrade || descriptor == inventoryUpgrade) {
|
||||||
else if (descriptor == generatorUpgrade) 0
|
if (descriptor == generatorUpgrade && availableMountPoints.contains(MountPointName.BottomBack)) MountPointName.BottomBack
|
||||||
else 10
|
else if (descriptor == inventoryUpgrade && availableMountPoints.contains(MountPointName.TopBack)) MountPointName.TopBack
|
||||||
|
else MountPointName.Any
|
||||||
|
}
|
||||||
|
else MountPointName.None
|
||||||
}
|
}
|
||||||
|
|
||||||
def canRender(stack: ItemStack): Boolean = {
|
def canRender(stack: ItemStack): Boolean = {
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.base.Strings
|
|||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.api.driver.item.UpgradeRenderer
|
import li.cil.oc.api.driver.item.UpgradeRenderer
|
||||||
|
import li.cil.oc.api.driver.item.UpgradeRenderer.MountPointName
|
||||||
import li.cil.oc.api.event.RobotRenderEvent
|
import li.cil.oc.api.event.RobotRenderEvent
|
||||||
import li.cil.oc.client.Textures
|
import li.cil.oc.client.Textures
|
||||||
import li.cil.oc.common.EventHandler
|
import li.cil.oc.common.EventHandler
|
||||||
@ -19,6 +20,7 @@ import net.minecraft.client.renderer.entity.RendererLivingEntity
|
|||||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||||
import net.minecraft.init.Items
|
import net.minecraft.init.Items
|
||||||
import net.minecraft.item.ItemBlock
|
import net.minecraft.item.ItemBlock
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.EnumChatFormatting
|
import net.minecraft.util.EnumChatFormatting
|
||||||
import net.minecraft.util.Vec3
|
import net.minecraft.util.Vec3
|
||||||
@ -30,11 +32,24 @@ import net.minecraftforge.common.util.ForgeDirection
|
|||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
import org.lwjgl.opengl.GL12
|
import org.lwjgl.opengl.GL12
|
||||||
|
|
||||||
|
import scala.collection.convert.WrapAsJava._
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
object RobotRenderer extends TileEntitySpecialRenderer {
|
object RobotRenderer extends TileEntitySpecialRenderer {
|
||||||
private val displayList = GLAllocation.generateDisplayLists(2)
|
private val displayList = GLAllocation.generateDisplayLists(2)
|
||||||
|
|
||||||
private val mountPoints = Array.fill(7)(new RobotRenderEvent.MountPoint())
|
private val mountPoints = Array.fill(7)(new RobotRenderEvent.MountPoint())
|
||||||
|
|
||||||
|
private val slotNameMapping = Map(
|
||||||
|
UpgradeRenderer.MountPointName.TopLeft -> 0,
|
||||||
|
UpgradeRenderer.MountPointName.TopRight -> 1,
|
||||||
|
UpgradeRenderer.MountPointName.TopBack -> 2,
|
||||||
|
UpgradeRenderer.MountPointName.BottomLeft -> 3,
|
||||||
|
UpgradeRenderer.MountPointName.BottomRight -> 4,
|
||||||
|
UpgradeRenderer.MountPointName.BottomBack -> 5,
|
||||||
|
UpgradeRenderer.MountPointName.BottomFront -> 6
|
||||||
|
)
|
||||||
|
|
||||||
private val gap = 1.0f / 28.0f
|
private val gap = 1.0f / 28.0f
|
||||||
private val gt = 0.5f + gap
|
private val gt = 0.5f + gap
|
||||||
private val gb = 0.5f - gap
|
private val gb = 0.5f - gap
|
||||||
@ -405,20 +420,31 @@ object RobotRenderer extends TileEntitySpecialRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (MinecraftForgeClient.getRenderPass == 0) {
|
if (MinecraftForgeClient.getRenderPass == 0) {
|
||||||
var filterMount = 0
|
lazy val availableSlots = slotNameMapping.keys.to[mutable.Set]
|
||||||
//noinspection SortFilter We need to sort before we filter, because the filter is index sensitive.
|
lazy val wildcardRenderers = mutable.Buffer.empty[(ItemStack, UpgradeRenderer)]
|
||||||
val stacks = (robot.componentSlots ++ robot.containerSlots).map(robot.getStackInSlot).
|
lazy val slotMapping = Array.fill(mountPoints.length)(null: (ItemStack, UpgradeRenderer))
|
||||||
collect { case stack if stack != null && stack.getItem.isInstanceOf[UpgradeRenderer] => (stack, stack.getItem.asInstanceOf[UpgradeRenderer]) }.
|
|
||||||
sortBy { case (stack, renderer) => -renderer.priority(stack, robot) }.
|
val renderers = (robot.componentSlots ++ robot.containerSlots).map(robot.getStackInSlot).
|
||||||
filter {
|
collect { case stack if stack != null && stack.getItem.isInstanceOf[UpgradeRenderer] => (stack, stack.getItem.asInstanceOf[UpgradeRenderer]) }
|
||||||
case (stack, renderer) if filterMount < mountPoints.length && renderer.canRender(stack, mountPoints(filterMount), robot) =>
|
|
||||||
filterMount += 1
|
for ((stack, renderer) <- renderers) {
|
||||||
true
|
val preferredSlot = renderer.computePreferredMountPoint(stack, robot, availableSlots)
|
||||||
case _ => false
|
if (availableSlots.remove(preferredSlot)) {
|
||||||
|
slotMapping(slotNameMapping(preferredSlot)) = (stack, renderer)
|
||||||
|
}
|
||||||
|
else if (preferredSlot == MountPointName.Any) {
|
||||||
|
wildcardRenderers += ((stack, renderer))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val minLength = math.min(mountPoints.length, stacks.length)
|
var firstEmpty = slotMapping.indexOf(null)
|
||||||
for (((stack, renderer), mountPoint) <- (stacks.take(minLength), mountPoints.take(minLength)).zipped) try {
|
for (entry <- wildcardRenderers if firstEmpty >= 0) {
|
||||||
|
slotMapping(firstEmpty) = entry
|
||||||
|
firstEmpty = slotMapping.indexOf(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((info, mountPoint) <- (slotMapping, mountPoints).zipped if info != null) try {
|
||||||
|
val (stack, renderer) = info
|
||||||
GL11.glPushMatrix()
|
GL11.glPushMatrix()
|
||||||
GL11.glTranslatef(0.5f, 0.5f, 0.5f)
|
GL11.glTranslatef(0.5f, 0.5f, 0.5f)
|
||||||
renderer.render(stack, mountPoint, robot, f)
|
renderer.render(stack, mountPoint, robot, f)
|
||||||
|
@ -254,9 +254,7 @@ class Delegator extends Item with driver.item.UpgradeRenderer {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
def priority(stack: ItemStack, robot: Robot): Int = UpgradeRenderer.priority(stack)
|
override def computePreferredMountPoint(stack: ItemStack, robot: Robot, availableMountPoints: util.Set[String]): String = UpgradeRenderer.preferredMountPoint(stack, availableMountPoints)
|
||||||
|
|
||||||
def canRender(stack: ItemStack, mountPoint: MountPoint, robot: Robot): Boolean = UpgradeRenderer.canRender(stack)
|
override def render(stack: ItemStack, mountPoint: MountPoint, robot: Robot, pt: Float): Unit = UpgradeRenderer.render(stack, mountPoint)
|
||||||
|
|
||||||
def render(stack: ItemStack, mountPoint: MountPoint, robot: Robot, pt: Float): Unit = UpgradeRenderer.render(stack, mountPoint)
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user