public WeightedRandomModel(ModelResourceLocation parent, Variants variants) { this.variants = variants.getVariants(); ImmutableList.Builder<Pair<IModel, IModelState>> builder = ImmutableList.builder(); for (Variant v : (List<Variant>) variants.getVariants()) { ResourceLocation loc = v.getModelLocation(); locations.add(loc); IModel model = null; try { model = getModel(loc); } catch (Exception e) { /* * Vanilla eats this, which makes it only show variants that have models. * But that doesn't help debugging, so we maintain the missing model * so that resource pack makers have a hint that their states are broken. */ FMLLog.warning( "Unable to load block model: \'" + loc + "\' for variant: \'" + parent + "\': " + e.toString()); model = getMissingModel(); } if (v instanceof ISmartVariant) { model = ((ISmartVariant) v).process(model, ModelLoader.this); try { resolveDependencies(model); } catch (IOException e) { FMLLog.getLogger() .error("Exception resolving indirect dependencies for model" + loc, e); } textures.addAll(model.getTextures()); // Kick this, just in case. } models.add(model); builder.add(Pair.of(model, v.getState())); } if (models.size() == 0) // If all variants are missing, add one with the missing model and default rotation. { IModel missing = getMissingModel(); models.add(missing); builder.add(Pair.<IModel, IModelState>of(missing, TRSRTransformation.identity())); } defaultState = new MultiModelState(builder.build()); }
public static void revertToFrozen() { if (frozen == null) { FMLLog.warning("Can't revert to frozen GameData state without freezing first."); } else { FMLLog.fine("Reverting to frozen data state."); getMain().set(frozen); } // the id mapping has reverted, fire remap events for those that care about id changes Loader.instance() .fireRemapEvent(ImmutableMap.<String, Integer[]>of(), ImmutableMap.<String, Integer[]>of()); // the id mapping has reverted, ensure we sync up the object holders ObjectHolderRegistry.INSTANCE.applyObjectHolders(); }
/** * Registers a ore item into the dictionary. Raises the registerOre function in all registered * handlers. * * @param name The name of the ore * @param ore The ore's ItemStack */ private static void registerOreImpl(String name, ItemStack ore) { if ("Unknown".equals(name)) return; // prevent bad IDs. if (ore == null || ore.getItem() == null) { FMLLog.bigWarning( "Invalid registration attempt for an Ore Dictionary item with name %s has occurred. The registration has been denied to prevent crashes. The mod responsible for the registration needs to correct this.", name); return; // prevent bad ItemStacks. } int oreID = getOreID(name); // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to // a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not // aware of the item yet // IT should be noted that -1 will fail the gate further down, if an entry already exists with // value -1 for this name. This is what is broken and being warned about. // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes // - you can't make them properly until you've registered with the game. ResourceLocation registryName = ore.getItem().delegate.name(); int hash; if (registryName == null) { FMLLog.bigWarning( "A broken ore dictionary registration with name %s has occurred. It adds an item (type: %s) which is currently unknown to the game registry. This dictionary item can only support a single value when" + " registered with ores like this, and NO I am not going to turn this spam off. Just register your ore dictionary entries after the GameRegistry.\n" + "TO USERS: YES this is a BUG in the mod " + Loader.instance().activeModContainer().getName() + " report it to them!", name, ore.getItem().getClass()); hash = -1; } else { hash = GameData.getItemRegistry().getId(registryName); } if (ore.getItemDamage() != WILDCARD_VALUE) { hash |= ((ore.getItemDamage() + 1) << 16); // +1 so 0 is significant } // Add things to the baked version, and prevent duplicates List<Integer> ids = stackToId.get(hash); if (ids != null && ids.contains(oreID)) return; if (ids == null) { ids = Lists.newArrayList(); stackToId.put(hash, ids); } ids.add(oreID); // Add to the unbaked version ore = ore.copy(); idToStack.get(oreID).add(ore); MinecraftForge.EVENT_BUS.post(new OreRegisterEvent(name, ore)); }
@Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { if (this.state != null) { FMLLog.getLogger() .log( Level.INFO, "Opening channel which already seems to have a state set. This is a vanilla connection. Handshake handler will stop now"); return; } FMLLog.getLogger().log(Level.TRACE, "Handshake channel activating"); this.state = ConnectionState.OPENING; // send ourselves as a user event, to kick the pipeline active this.handshakeChannel.pipeline().fireUserEventTriggered(this); this.manager.channel().config().setAutoRead(true); }
public static void rebakeMap() { // System.out.println("Baking OreDictionary:"); stackToId.clear(); for (int id = 0; id < idToStack.size(); id++) { List<ItemStack> ores = idToStack.get(id); if (ores == null) continue; for (ItemStack ore : ores) { // HACK: use the registry name's ID. It is unique and it knows about substitutions ResourceLocation name = ore.getItem().delegate.name(); int hash; if (name == null) { FMLLog.log( Level.DEBUG, "Defaulting unregistered ore dictionary entry for ore dictionary %s: type %s to -1", getOreName(id), ore.getItem().getClass()); hash = -1; } else { hash = GameData.getItemRegistry().getId(name); } if (ore.getItemDamage() != WILDCARD_VALUE) { hash |= ((ore.getItemDamage() + 1) << 16); // +1 so meta 0 is significant } List<Integer> ids = stackToId.get(hash); if (ids == null) { ids = Lists.newArrayList(); stackToId.put(hash, ids); } ids.add(id); // System.out.println(id + " " + getOreName(id) + " " + Integer.toHexString(hash) + " " + // ore); } } }
/** * Gets all the integer ID for the ores that the specified item stack is registered to. If the * item stack is not linked to any ore, this will return an empty array and no new entry will be * created. * * @param stack The item stack of the ore. * @return An array of ids that this ore is registered as. */ public static int[] getOreIDs(ItemStack stack) { if (stack == null || stack.getItem() == null) throw new IllegalArgumentException("Stack can not be null!"); Set<Integer> set = new HashSet<Integer>(); // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to // a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not // aware of the item yet // IT should be noted that -1 will fail the gate further down, if an entry already exists with // value -1 for this name. This is what is broken and being warned about. // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes // - you can't make them properly until you've registered with the game. ResourceLocation registryName = stack.getItem().delegate.name(); int id; if (registryName == null) { FMLLog.log( Level.DEBUG, "Attempted to find the oreIDs for an unregistered object (%s). This won't work very well.", stack); return new int[0]; } else { id = GameData.getItemRegistry().getId(registryName); } List<Integer> ids = stackToId.get(id); if (ids != null) set.addAll(ids); ids = stackToId.get(id | ((stack.getItemDamage() + 1) << 16)); if (ids != null) set.addAll(ids); Integer[] tmp = set.toArray(new Integer[set.size()]); int[] ret = new int[tmp.length]; for (int x = 0; x < tmp.length; x++) ret[x] = tmp[x]; return ret; }
private void testConsistency() { // test if there's an entry for every set bit in availabilityMap for (int i = availabilityMap.nextSetBit(0); i >= 0; i = availabilityMap.nextSetBit(i + 1)) { if (iBlockRegistry.getRaw(i) == null && iItemRegistry.getRaw(i) == null && !blockedIds.contains(i)) { throw new IllegalStateException( String.format("availabilityMap references empty entries for id %d.", i)); } } for (int pass = 0; pass < 2; pass++) { boolean isBlock = pass == 0; String type = isBlock ? "block" : "item"; FMLControlledNamespacedRegistry<?> registry = isBlock ? iBlockRegistry : iItemRegistry; registry.validateContent( (isBlock ? MAX_BLOCK_ID : MAX_ITEM_ID), type, availabilityMap, blockedIds, iBlockRegistry); } FMLLog.fine("Registry consistency check successful"); }
@Override public IFlexibleBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) { IFlexibleBakedModel bakedBase = null; if (base != null) bakedBase = base.bake(state, format, bakedTextureGetter); ImmutableMap.Builder<String, IFlexibleBakedModel> mapBuilder = ImmutableMap.builder(); for (Entry<String, Pair<IModel, IModelState>> entry : parts.entrySet()) { Pair<IModel, IModelState> pair = entry.getValue(); mapBuilder.put( entry.getKey(), pair.getLeft().bake(pair.getRight(), format, bakedTextureGetter)); } if (bakedBase == null && parts.isEmpty()) { FMLLog.log( Level.ERROR, "MultiModel %s is empty (no base model or parts were provided/resolved)", location); IModel missing = ModelLoaderRegistry.getMissingModel(); return missing.bake(missing.getDefaultState(), format, bakedTextureGetter); } return new Baked(location, true, bakedBase, mapBuilder.build()); }
public static void freezeData() { FMLLog.fine("Freezing block and item id maps"); getMain().testConsistency(); frozen = new GameData(getMain()); frozen.testConsistency(); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof ConnectionType && side == Side.SERVER) { FMLLog.info("Timeout occurred, assuming a vanilla client"); kickVanilla(); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // Stop the epic channel closed spam at close if (!(cause instanceof ClosedChannelException)) { FMLLog.log(Level.ERROR, cause, "NetworkDispatcher exception"); } super.exceptionCaught(ctx, cause); }
private boolean handleVanilla(Packet msg) { if (state == ConnectionState.AWAITING_HANDSHAKE && msg instanceof S01PacketJoinGame) { handshakeChannel.pipeline().fireUserEventTriggered(msg); } else { FMLLog.info( "Unexpected packet during modded negotiation - assuming vanilla or keepalives : %s", msg.getClass().getName()); } return false; }
public void onPostBakeEvent(IRegistry<ModelResourceLocation, IBakedModel> modelRegistry) { IBakedModel missingModel = modelRegistry.getObject(MODEL_MISSING); for (ModelResourceLocation missing : missingVariants) { IBakedModel model = modelRegistry.getObject(missing); if (model == null || model == missingModel) { FMLLog.severe("Model definition for location %s not found", missing); } } isLoading = false; }
public void completeHandshake(Side target) { if (state == ConnectionState.CONNECTED) { FMLLog.severe("Attempt to double complete the network connection!"); throw new FMLNetworkException("Attempt to double complete!"); } if (side == Side.CLIENT) { completeClientSideConnection(ConnectionType.MODDED); } else { this.state = ConnectionState.FINALIZING; // Delay and finalize in the world tick loop. } }
private void completeClientSideConnection(ConnectionType type) { this.connectionType = type; FMLLog.info( "[%s] Client side %s connection established", Thread.currentThread().getName(), this.connectionType.name().toLowerCase(Locale.ENGLISH)); this.state = ConnectionState.CONNECTED; FMLCommonHandler.instance() .bus() .post( new FMLNetworkEvent.ClientConnectedToServerEvent(manager, this.connectionType.name())); }
int registerBlock(Block block, String name) // from GameRegistry { int index = name.indexOf(':'); if (name.indexOf(':') != -1) FMLLog.bigWarning( "Illegal extra prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); name = addPrefix(name); return registerBlock(block, name, -1); }
public static TileEntity func_190200_a(World p_190200_0_, NBTTagCompound p_190200_1_) { TileEntity tileentity = null; String s = p_190200_1_.getString("id"); Class<? extends TileEntity> oclass = null; try { oclass = nameToClassMap.get(s); if (oclass != null) { tileentity = (TileEntity) oclass.newInstance(); } } catch (Throwable throwable1) { LOGGER.error("Failed to create block entity {}", new Object[] {s, throwable1}); net.minecraftforge.fml.common.FMLLog.log( org.apache.logging.log4j.Level.ERROR, throwable1, "A TileEntity %s(%s) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", s, oclass.getName()); } if (tileentity != null) { try { tileentity.func_190201_b(p_190200_0_); tileentity.readFromNBT(p_190200_1_); } catch (Throwable throwable) { LOGGER.error("Failed to load data for block entity {}", new Object[] {s, throwable}); net.minecraftforge.fml.common.FMLLog.log( org.apache.logging.log4j.Level.ERROR, throwable, "A TileEntity %s(%s) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", s, oclass.getName()); tileentity = null; } } else { LOGGER.warn("Skipping BlockEntity with id {}", new Object[] {s}); } return tileentity; }
/** * Retrieves the proxy for black/whitelist-based API queries. * * @return The proxy for black/whitelist-based API queries */ public static IBlacklistProxy getBlacklistProxy() { if (blacklistProxy == null) { try { Class<?> clazz = Class.forName("moze_intel.projecte.impl.BlacklistProxyImpl"); blacklistProxy = (IBlacklistProxy) clazz.getField("instance").get(null); } catch (ReflectiveOperationException ex) { FMLLog.warning( "[ProjectEAPI] Error retrieving BlacklistProxyImpl, ProjectE may be absent, damaged, or outdated."); } } return blacklistProxy; }
@Override public ModelFluid process(ImmutableMap<String, String> customData) { if (!customData.containsKey("fluid")) return this; String fluidStr = customData.get("fluid"); JsonElement e = new JsonParser().parse(fluidStr); String fluid = e.getAsString(); if (!FluidRegistry.isFluidRegistered(fluid)) { FMLLog.severe("fluid '%s' not found", fluid); return WATER; } return new ModelFluid(FluidRegistry.getFluid(fluid)); }
public void serverToClientHandshake(EntityPlayerMP player) { this.player = player; insertIntoChannel(); Boolean fml = this.manager.channel().attr(NetworkRegistry.FML_MARKER).get(); if (fml != null && fml.booleanValue()) { // FML on client, send server hello // TODO: Make this cleaner as it uses netty magic 0.o } else { serverInitiateHandshake(); FMLLog.info("Connection received without FML marker, assuming vanilla."); this.completeServerSideConnection(ConnectionType.VANILLA); } }
private List<String> loadGenericRegistries(GameDataSnapshot snapshot, GameData existing) { List<String> result = Lists.newArrayList(); for (Map.Entry<String, FMLControlledNamespacedRegistry<?>> e : existing.genericRegistries.entrySet()) { String regName = e.getKey(); FMLControlledNamespacedRegistry<?> registry = e.getValue(); FMLControlledNamespacedRegistry<?> newRegistry = genericRegistries.get(regName); if (newRegistry == null) { newRegistry = registry.makeShallowCopy(); genericRegistries.put(regName, newRegistry); } GameDataSnapshot.Entry regSnap = snapshot.entries.get("fmlgr:" + regName); if (regSnap == null) { FMLLog.info( "Weird, there was no registry data for registry %s found in the snapshot", regName); continue; } for (Entry<String, Integer> entry : regSnap.ids.entrySet()) { String entryName = entry.getKey(); int entryId = entry.getValue(); int currId = registry.getId(entryName); if (currId == -1) { FMLLog.info("Found a missing id in registry %s from the world %s", regName, entryName); result.add(regName + "{" + entryName + "}=" + entryId); continue; // no block/item -> nothing to add } else if (currId != entryId) { FMLLog.fine( "Fixed registry %s id mismatch %s: %d (init) -> %d (map).", regName, entryName, currId, entryId); } newRegistry.add(entryId, entryName, registry.getRaw(entryName)); } } return result; }
private synchronized void completeServerSideConnection(ConnectionType type) { this.connectionType = type; FMLLog.info( "[%s] Server side %s connection established", Thread.currentThread().getName(), this.connectionType.name().toLowerCase(Locale.ENGLISH)); this.state = ConnectionState.CONNECTED; FMLCommonHandler.instance() .bus() .post(new FMLNetworkEvent.ServerConnectionFromClientEvent(manager)); if (DEBUG_HANDSHAKE) manager.closeChannel( new ChatComponentText("Handshake Complete review log file for details.")); scm.initializeConnectionToPlayer(manager, player, serverHandler); }
private void verifyItemBlockName(ItemBlock item) { Object blockName = iBlockRegistry.getNameForObject(item.block); Object itemName = iItemRegistry.getNameForObject(item); // Vanilla has a mismatch: // Block <-> ItemBlock name mismatch, block name minecraft:standing_banner, item name // minecraft:banner // TODO: Untie these in the rest of the registry if (blockName != null && !blockName.equals(itemName) && !"minecraft:standing_banner".equals(blockName.toString())) { FMLLog.bigWarning( "Block <-> ItemBlock name mismatch, block name %s, item name %s", blockName, itemName); } }
private void resize(int x, int y, int z) { if (x <= 0 || x > MAX_X_SIZE || y <= 0 || y > MAX_Y_SIZE || z <= 0 || z > MAX_Z_SIZE) { FMLLog.severe("Out-of-range [x,y,z] in VoxelSelection constructor: [%d, %d, %d]", x, y, z); x = 1; y = 1; z = 1; } xSize = x; ySize = y; zSize = z; if (voxels == null) { voxels = new BitSet(xSize * ySize * zSize); // default to all false } else { voxels.clear(); } }
private FMLControlledNamespacedRegistry<?> findRegistry(Class<?> type) { BiMap<Class<?>, String> typeReg = registryTypes.inverse(); String name = typeReg.get(type); if (name == null) { Set<Class<?>> parents = Sets.newHashSet(); findSuperTypes(type, parents); SetView<Class<?>> foundType = Sets.intersection(parents, registryTypes.values()); if (foundType.isEmpty()) { FMLLog.severe("Unable to find registry for type %s", type.getName()); throw new IllegalArgumentException( "Attempt to register an object without an associated registry"); } Class<?> regtype = Iterables.getOnlyElement(foundType); name = typeReg.get(regtype); } return genericRegistries.get(name); }
private int registerBlock(Block block, String name, int idHint) { // handle ItemBlock-before-Block registrations ItemBlock itemBlock = null; for (Item item : iItemRegistry.typeSafeIterable()) // find matching ItemBlock { if (item instanceof ItemBlock && ((ItemBlock) item).block == block) { itemBlock = (ItemBlock) item; break; } } if (itemBlock != null) // has ItemBlock, adjust id and clear the slot already occupied by the // corresponding item { idHint = iItemRegistry.getId(itemBlock); FMLLog.fine("Found matching ItemBlock %s for Block %s at id %d", itemBlock, block, idHint); freeSlot( idHint, block); // temporarily free the slot occupied by the Item for the block registration } // add int blockId = iBlockRegistry.add(idHint, name, block, availabilityMap); if (itemBlock != null) // verify { if (blockId != idHint) throw new IllegalStateException( String.format( "Block at itemblock id %d insertion failed, got id %d.", idHint, blockId)); verifyItemBlockName(itemBlock); } useSlot(blockId); ((RegistryDelegate.Delegate<Block>) block.delegate).setName(name); for (IBlockState state : ((List<IBlockState>) block.getBlockState().getValidStates())) { GameData.BLOCKSTATE_TO_ID.put(state, blockId << 4 | block.getMetaFromState(state)); } return blockId; }
/** * Adds a Chapter (or overrides one that already exists) * * @param chapter Chapter to add */ public void addChapter(Chapter chapter) { for (Chapter chap : chapters) if (chap.identifier.equals(chapter.identifier)) { chap = chapter; return; } if (chapters.length < 7) { Chapter[] newchap = new Chapter[chapters.length + 1]; for (int i = 0; i < chapters.length; i++) newchap[i] = chapters[i]; newchap[chapters.length] = chapter; chapters = newchap; } else FMLLog.log( "AbyssalCraftAPI", Level.ERROR, "NecroData instance is already full, can't add a new Chapter!"); }
@SuppressWarnings("unchecked") private <T> FMLControlledNamespacedRegistry<T> createGenericRegistry( String registryName, Class<T> type, int minId, int maxId) { Set<Class<?>> parents = Sets.newHashSet(); findSuperTypes(type, parents); SetView<Class<?>> overlappedTypes = Sets.intersection(parents, registryTypes.values()); if (!overlappedTypes.isEmpty()) { Class<?> foundType = overlappedTypes.iterator().next(); FMLLog.severe( "Found existing registry of type %1s named %2s, you cannot create a new registry (%3s) with type %4s, as %4s has a parent of that type", foundType, registryTypes.inverse().get(foundType), registryName, type); throw new IllegalArgumentException( "Duplicate registry parent type found - you can only have one registry for a particular super type"); } FMLControlledNamespacedRegistry<?> fmlControlledNamespacedRegistry = new FMLControlledNamespacedRegistry<T>(null, maxId, minId, type); genericRegistries.put(registryName, fmlControlledNamespacedRegistry); registryTypes.put(registryName, type); return (FMLControlledNamespacedRegistry<T>) fmlControlledNamespacedRegistry; }
/** ■視線先のEntityを捕捉する EntityRender.getMouseOver()をぱくぱく */ @Override public List<MovingObjectPosition> getEntity(ItemStack itemStackIn, EntityPlayer playerIn) { List<MovingObjectPosition> targets = new ArrayList<MovingObjectPosition>(); // new ArrayList<MovingObjectPosition>(); if (playerIn != null && playerIn.worldObj != null) { MovingObjectPosition blockMOP = null; // ■りふれくしょん! Timer timer; try { timer = ObfuscationReflectionHelper.getPrivateValue( Minecraft.class, Minecraft.getMinecraft(), 19); } catch (UnableToAccessFieldException e) { FMLLog.log(Level.ERROR, e, "りふれくしょん! に失敗しました!>< ClientProxy.getEntity()"); throw e; } // ■レンジ(チンッ!) double range = 20d; // ■直近のブロックとの距離 double nearBlockRange = 0; // ■れいとれーす! // (プレイヤーの視線の先で最寄のブロックまでの距離を返す。 // ブロックが無かったら指定したレンジぐらいのアタイ!を返す) // TODO 奈落とか天上だとどうなるか要検証 blockMOP = playerIn.rayTrace(range, timer.renderPartialTicks); // ■プレイヤーの視点位置 // (renderPartialTicks:0.0 - 1.0) 一回前の描画位置からどれだけ動いたかの比率(?)として使ってる(?) Vec3 playerEyePos = playerIn.getPositionEyes(timer.renderPartialTicks); // ■入手したモップがある if (blockMOP != null) { // ■「プレイヤーの視点」と「最寄ブロック」との距離を取得 nearBlockRange = blockMOP.hitVec.distanceTo(playerEyePos); } // ■プレイヤーの視線(単位ベクトル)(ベクトルに乗算するメソッドが無い事に驚愕) Vec3 playerSight = playerIn.getLook(timer.renderPartialTicks); // ■プレイヤーの視線(レンジ) Vec3 playerRange = playerEyePos.addVector( playerSight.xCoord * range, playerSight.yCoord * range, playerSight.zCoord * range); // ■プレイヤーの視線(立方体)に入っているEntityをかき集める float f1 = 1.0f; // 立方体拡張(上下に1.0F) AxisAlignedBB aabb1 = playerIn .getEntityBoundingBox() .addCoord( playerSight.xCoord * range, playerSight.yCoord * range, playerSight.zCoord * range) .expand(f1, f1, f1); List<Entity> list = playerIn.worldObj.getEntitiesWithinAABBExcludingEntity(playerIn, aabb1); // TODO ごり押し君(SOWはEntityWeatherの為) list.addAll(playerIn.worldObj.weatherEffects); // ■Entity! 君に決めた! 枠 Entity mob = null; Vec3 mobDist = null; double mobRange = nearBlockRange; Entity sow = null; Vec3 sowDist = null; double sowRange = nearBlockRange; // ■かき集めたEntity共をチェックしていく(candidate:候補者) for (Entity candidate : list) { // ■「判定なし」かつ「SOWでは無い」を満たすEntityはスルー // if (!candidate.canBeCollidedWith() && !(candidate instanceof EntitySOW)) { continue; } // ■ドラゴン(概念)は対象外 if (candidate instanceof EntityDragon) { continue; } // ■「not 生物」かつ「not ドラゴンパーツ」かつ「not SOW」を満たすEntityはスルー if (!(candidate instanceof EntityLivingBase) && !(candidate instanceof EntityDragonPart) && !(candidate instanceof EntitySOW)) { continue; } // ■ターゲットの当たり判定を拡張 float fExpand = candidate.getCollisionBorderSize() * 3f; AxisAlignedBB aabb2 = candidate.getEntityBoundingBox().expand(fExpand, fExpand, fExpand); // ■拡張したターゲットの当たり判定と視線(レンジ)が交差するなら、モップが帰る MovingObjectPosition targetMOP = aabb2.calculateIntercept(playerEyePos, playerRange); // ■ターゲットの中、あったかいナリ(当たり判定が重なってる) if (aabb2.isVecInside(playerEyePos)) { // ■Entityの種類によって格納するインスタンスを分ける if (candidate instanceof EntitySOW) { // ■距離が近いので更新 if (0.0D < sowRange || sowRange == 0.0D) { sow = candidate; sowDist = targetMOP == null ? playerEyePos : targetMOP.hitVec; sowRange = 0.0D; } } else { // ■距離が近いので更新 if (0.0D < mobRange || mobRange == 0.0D) { mob = candidate; mobDist = targetMOP == null ? playerEyePos : targetMOP.hitVec; mobRange = 0.0D; } } } // ■帰ってきたモップ else if (targetMOP != null) { double range2 = playerEyePos.distanceTo(targetMOP.hitVec); // ■前に調べた奴より距離が近い if (candidate instanceof EntitySOW) { if (range2 < sowRange || sowRange == 0.0D) { sow = candidate; sowDist = targetMOP.hitVec; sowRange = range2; } } else { if (range2 < mobRange || mobRange == 0.0D) { // ■現在乗ってるEntity かつ 対象Entityに乗った状態で右クリックが有効か否か(このメソッド、使えそう) if (candidate == playerIn.ridingEntity && !candidate.canRiderInteract()) { // TODO このシーケンスには入れるの? if (mobRange == 0.0D) { mob = candidate; mobDist = targetMOP.hitVec; } } else { mob = candidate; mobDist = targetMOP.hitVec; mobRange = range2; } } } } } // ■調べ終えました。 // 「ターゲット」が居る かつ // (「ターゲットの間にブロックが無い」 または // 「モップがヌルポ(TODO どうやったらこの条件になるか要検証)」) if (mob != null && (mobRange < nearBlockRange || blockMOP == null)) { // mop = new MovingObjectPosition(mob, mobDist); targets.add(new MovingObjectPosition(mob, mobDist)); // TODO // System.out.println("targets.add(mob) = " + mob.getName()); } if (sow != null && (sowRange < nearBlockRange || blockMOP == null)) { targets.add(new MovingObjectPosition(sow, sowDist)); // TODO // System.out.println("targets.add(sow) = " + sow.getName()); } } return targets; }
private int registerItem(Item item, String name, int idHint) { if (item instanceof ItemBlock && !(item instanceof ItemBanner)) // ItemBlock, adjust id and clear the slot already occupied by the // corresponding block { Block block = ((ItemBlock) item).block; if (idHint != -1 && getMain().blockSubstitutions.containsKey(name)) { block = getMain().blockSubstitutions.get(name); } int id = iBlockRegistry.getId(block); if (id == -1) // ItemBlock before its Block { if (idHint < 0 || availabilityMap.get(idHint) || idHint > MAX_BLOCK_ID) // non-suitable id, allocate one in the block id range, add would // use the item id range otherwise { id = availabilityMap.nextClearBit( MIN_BLOCK_ID); // find suitable id here, iItemRegistry would search from // MIN_ITEM_ID if (id > MAX_BLOCK_ID) throw new RuntimeException( String.format("Invalid id %d - maximum id range exceeded.", id)); FMLLog.fine( "Allocated id %d for ItemBlock %s in the block id range, original id requested: %d.", id, name, idHint); } else // idHint is suitable without changes { id = idHint; } } else // ItemBlock after its Block { if (FMLControlledNamespacedRegistry.DEBUG) FMLLog.fine( "Found matching Block %s for ItemBlock %s at id %d, original id requested: %d", block, item, id, idHint); freeSlot( id, item); // temporarily free the slot occupied by the Block for the item registration } idHint = id; } int itemId = iItemRegistry.add(idHint, name, item, availabilityMap); if (item instanceof ItemBlock) // verify { if (itemId != idHint) throw new IllegalStateException( String.format("ItemBlock at block id %d insertion failed, got id %d.", idHint, itemId)); verifyItemBlockName((ItemBlock) item); } // block the Block Registry slot with the same id useSlot(itemId); ((RegistryDelegate.Delegate<Item>) item.delegate).setName(name); return itemId; }