Browse Source

improvements for release

pull/1/head
Adrian Siekierka 2 years ago
parent
commit
09ce459357

+ 4
- 0
docs/licenses/LICENSE.oneko View File

@@ -9,3 +9,7 @@ Copyright (c) 1990 Kiichiroh Mukose

The (Japanese) README file, as well as the LSM file originally distributed
with oneko on sunsite both say that oneko is public domain software.

Sakura Kinomoto and Tomoyo Daidouji are characters in a comic strip
"CARDCAPTOR SAKURA" (CLAMP, Kodansha), with the sanction indicated in
CLAMP SCHOOL WEB CAMPUS (http://www.clamp.f-2.co.jp/).

+ 78
- 6
src/main/java/pl/asie/inventoryneko/InventoryNeko.java View File

@@ -19,16 +19,27 @@

package pl.asie.inventoryneko;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFlower;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.DungeonHooks;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.ForgeRegistries;

import java.util.HashMap;
import java.util.Map;
@@ -46,9 +57,14 @@ public class InventoryNeko {

@SidedProxy(modId = "inventoryneko", clientSide = "pl.asie.inventoryneko.ProxyClient", serverSide = "pl.asie.inventoryneko.ProxyCommon")
public static ProxyCommon proxy;
public static Configuration config;

private static Multimap<String, Item> itemMultimap = HashMultimap.create();

public static void registerNeko(NekoDefinition definition) {
NEKO.put(definition.getName(), definition);
if ("neko".equals(definition.getName()) || config.getBoolean(definition.getName(), "enabled", true, "Is " + definition.getName() + " enabled?")) {
NEKO.put(definition.getName(), definition);
}
}

public static void registerState(NekoState animation) {
@@ -69,13 +85,59 @@ public class InventoryNeko {
return Integer.compare(v, 0);
}

public static boolean isFood(ItemStack stack) {
if (stack.getItem() instanceof ItemFood) {
return true;
}

if (stack.getItem() == Items.CAKE) {
return true;
}

if (itemMultimap.get("food").contains(stack.getItem())) {
return true;
}

return false;
}

public static boolean isFlower(ItemStack stack) {
if (Block.getBlockFromItem(stack.getItem()) instanceof BlockFlower) {
return true;
}

if (stack.getItem() == Items.CAKE) {
return true;
}

if (itemMultimap.get("flower").contains(stack.getItem())) {
return true;
}

return false;
}

private void addItems(String name) {
String[] items = config.getStringList(name, "customItems", new String[0], "Use registry names.");
for (String s : items) {
if (s.indexOf(':') >= 0) {
ResourceLocation loc = new ResourceLocation(s);
if (ForgeRegistries.ITEMS.containsKey(loc)) {
itemMultimap.put(name, ForgeRegistries.ITEMS.getValue(loc));
}
}
}
}

@Mod.EventHandler
public void onPreInit(FMLPreInitializationEvent event) {
registerNeko(new NekoDefinition("neko", 250));
registerNeko(new NekoDefinition("tora", "neko", 250));
registerNeko(new NekoDefinition("dog", 250));
registerNeko(new NekoDefinition("sakura", 250));
registerNeko(new NekoDefinition("tomoyo", 250));
config = new Configuration(event.getSuggestedConfigurationFile());

registerNeko(new NekoDefinition("neko", 250, InventoryNeko::isFood));
registerNeko(new NekoDefinition("tora", "neko", 250, InventoryNeko::isFood));
registerNeko(new NekoDefinition("dog", 250, InventoryNeko::isFood));
registerNeko(new NekoDefinition("sakura", 250, InventoryNeko::isFlower));
registerNeko(new NekoDefinition("tomoyo", 250, InventoryNeko::isFlower));

registerState(new NekoState("awake", 1, 3));
registerState(new NekoState("dtogi", 2, 10));
@@ -107,6 +169,16 @@ public class InventoryNeko {
MinecraftForge.EVENT_BUS.register(proxy);
}

@Mod.EventHandler
public void onInit(FMLInitializationEvent event) {
addItems("food");
addItems("flower");

if (config.hasChanged()) {
config.save();
}
}

@SubscribeEvent
public void onRegisterItems(RegistryEvent.Register<Item> event) {
event.getRegistry().register(itemNeko);

+ 103
- 37
src/main/java/pl/asie/inventoryneko/ItemNeko.java View File

@@ -22,16 +22,14 @@ package pl.asie.inventoryneko;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;

import java.util.Random;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;

@@ -69,22 +67,68 @@ public class ItemNeko extends Item {
return Math.sqrt(xDiff * xDiff + yDiff * yDiff);
}

private int findAttractiveSlot(int slotWidth, int slotHeight, int slotPosition, Function<Integer, ItemStack> stackGetter) {
int r = -1;
double distance = Double.MAX_VALUE;

private int[] findNextSlot(NekoDefinition definition, int slotWidth, int slotHeight, int slotPosition, Function<Integer, ItemStack> stackGetter) {
int[] count = new int[slotWidth * slotHeight];
int[] from = new int[slotWidth * slotHeight];
for (int i = 0; i < slotWidth * slotHeight; i++) {
ItemStack stack = stackGetter.apply(i);
if (!stack.isEmpty() && (stack.getItem() instanceof ItemFood || stack.getItem() == Items.CAKE)) {
double dist2 = getDistance(i, slotPosition, slotWidth);
if (dist2 < distance) {
r = i;
distance = dist2;
from[i] = -1;
}

LinkedList<Integer> posQueue = new LinkedList<>();
posQueue.add(slotPosition);
from[slotPosition] = -2;

int lowestCount = Integer.MAX_VALUE;
int lowestPos = -1;

while (!posQueue.isEmpty()) {
int pos = posQueue.remove();

ItemStack stack = stackGetter.apply(pos);
if (pos != slotPosition && !stack.isEmpty()) {
if (definition.isInterestingStack(stack)) {
if (count[pos] < lowestCount) {
lowestCount = count[pos];
lowestPos = pos;
}
} else {
// no can do.
}
} else {
// can trespass
for (int y = (pos / slotWidth) - 1; y <= (pos / slotWidth) + 1; y++) {
for (int x = (pos % slotWidth) - 1; x <= (pos % slotWidth) + 1; x++) {
if (x >= 0 && y >= 0 && x < slotWidth && y < slotHeight) {
int posNew = y * slotWidth + x;
if (posNew != pos && (from[posNew] == -1 || (count[pos] + 1) < count[posNew])) {
ItemStack stackNew = stackGetter.apply(posNew);
if (definition.isInterestingStack(stackNew) && x != (pos % slotWidth) && y != (pos / slotWidth)) {
// must be adjacent to attracting stack
continue;
}

posQueue.add(posNew);
from[posNew] = pos;
count[posNew] = count[pos] + 1;
}
}
}
}
}
}

return r;
if (lowestPos < 0) {
return new int[]{-1, -1};
} else {
int p = lowestPos;
int[] p1 = new int[]{lowestPos, lowestPos};
while (from[p] != -2) {
p1[1] = p1[0];
p1[0] = p;
p = from[p];
}
return p1;
}
}

private boolean tryMove(ItemStack stack, int from, int to, Function<Integer, ItemStack> stackGetter, BiConsumer<Integer, ItemStack> stackSetter) {
@@ -112,15 +156,29 @@ public class ItemNeko extends Item {
boolean shouldChangeState = tick >= (state.getDuration(definition) - 1);

if (shouldChangeState) {
int slot = findAttractiveSlot(slotWidth, slotHeight, slotPosition, stackGetter);
if (slot < 0 || slot >= slotWidth*slotHeight) {
state = InventoryNeko.STATE.get("sleep");
int[] slot = findNextSlot(definition, slotWidth, slotHeight, slotPosition, stackGetter);
if (slot[0] < 0 || slot[0] >= slotWidth*slotHeight) {
if (!"sleep".equals(state.getName())) {
switch (random.nextInt(8)) {
case 1:
case 2:
case 7:
state = InventoryNeko.STATE.get("sleep");
break;
case 5:
state = InventoryNeko.STATE.get("mati3");
break;
default:
state = InventoryNeko.STATE.get("mati2");
break;
}
}
} else {
if (state.is("sleep")) {
state = InventoryNeko.STATE.get("awake");
} else {
double dist = getDistance(slot, slotPosition, slotWidth);
if (dist <= 1.0001d) {
ItemStack stackFound = stackGetter.apply(slot[0]);
if (definition.isInterestingStack(stackFound)) {
if (state.is("mati2")) {
switch (random.nextInt(40)) {
case 5:
@@ -139,29 +197,33 @@ public class ItemNeko extends Item {
}
}
} else {
int xDiff = (slot % slotWidth) - (slotPosition % slotWidth);
int yDiff = (slot / slotWidth) - (slotPosition / slotWidth);
int xDiff = (slot[0] % slotWidth) - (slotPosition % slotWidth);
int yDiff = (slot[0] / slotWidth) - (slotPosition / slotWidth);

if (xDiff > yDiff) {
if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(xDiff), stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(xDiff);
}

if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(yDiff) * slotWidth, stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(yDiff) * slotWidth;
}
if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(xDiff) + InventoryNeko.sign(yDiff) * slotWidth, stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(xDiff) + InventoryNeko.sign(yDiff) * slotWidth;
} else {
if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(yDiff) * slotWidth, stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(yDiff) * slotWidth;
}
if (xDiff > yDiff) {
if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(xDiff), stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(xDiff);
}

if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(yDiff) * slotWidth, stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(yDiff) * slotWidth;
}
} else {
if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(yDiff) * slotWidth, stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(yDiff) * slotWidth;
}

if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(xDiff), stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(xDiff);
if (tryMove(stack, slotPosition, slotPosition + InventoryNeko.sign(xDiff), stackGetter, stackSetter)) {
slotPosition = slotPosition + InventoryNeko.sign(xDiff);
}
}
}

xDiff = (slot % slotWidth) - (slotPosition % slotWidth);
yDiff = (slot / slotWidth) - (slotPosition / slotWidth);
xDiff = (slot[1] % slotWidth) - (slotPosition % slotWidth);
yDiff = (slot[1] / slotWidth) - (slotPosition / slotWidth);

if (xDiff < 0 && yDiff < 0) {
state = InventoryNeko.STATE.get("upleft");
@@ -200,11 +262,15 @@ public class ItemNeko extends Item {

@Override
public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) {
if (entityIn instanceof EntityPlayer && !(entityIn instanceof FakePlayer) && itemSlot < 36) {
// Creative mode inventories are bugged
if (entityIn instanceof EntityPlayer && !(entityIn instanceof FakePlayer) && !((EntityPlayer) entityIn).isCreative() && itemSlot >= 0 && itemSlot < 36) {
update(worldIn, stack, 9, 4, playerToView(itemSlot),
(i) -> ((EntityPlayer) entityIn).inventory.getStackInSlot(viewToPlayer(i)),
(i, s) -> ((EntityPlayer) entityIn).inventory.setInventorySlotContents(viewToPlayer(i), s)
);
} else {
InventoryNeko.getOrCreateTagCompound(stack).setString("state", "sleep");
InventoryNeko.getOrCreateTagCompound(stack).setInteger("tick", 0);
}
}


+ 16
- 7
src/main/java/pl/asie/inventoryneko/NekoDefinition.java View File

@@ -19,20 +19,29 @@

package pl.asie.inventoryneko;

import net.minecraft.item.ItemStack;

import java.util.function.Predicate;

public class NekoDefinition {
private String name;
private String maskName;
private int tickTime;
private final Predicate<ItemStack> isInteresting;
private final String name;
private final String maskName;
private final int tickTime;

public NekoDefinition(String name, int tickTime) {
this(name, name, tickTime);
public NekoDefinition(String name, int tickTime, Predicate<ItemStack> isInteresting) {
this(name, name, tickTime, isInteresting);
}


public NekoDefinition(String name, String maskName, int tickTime) {
public NekoDefinition(String name, String maskName, int tickTime, Predicate<ItemStack> isInteresting) {
this.name = name;
this.maskName = maskName;
this.tickTime = tickTime;
this.isInteresting = isInteresting;
}

public boolean isInterestingStack(ItemStack stack) {
return !stack.isEmpty() && isInteresting.test(stack);
}

public String getName() {

+ 56
- 4
src/main/java/pl/asie/inventoryneko/NekoInventoryTicker.java View File

@@ -22,21 +22,73 @@ package pl.asie.inventoryneko;
import com.google.common.collect.Sets;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.*;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.items.SlotItemHandler;
import org.apache.commons.lang3.tuple.Pair;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;
import java.util.*;

public class NekoInventoryTicker {
private Map<World, List<EntityItemFrame>> itemFrames = new HashMap<>();

private Set<Object> checkedInventories = Sets.newSetFromMap(new IdentityHashMap<>());

@SubscribeEvent
public void onWorldLoad(WorldEvent.Load event) {
if (event.getWorld().isRemote) return;
}

@SubscribeEvent
public void onWorldUnload(WorldEvent.Unload event) {
if (event.getWorld().isRemote) return;

itemFrames.remove(event.getWorld());
}

@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event) {
if (event.getWorld().isRemote) return;

if (event.getEntity() instanceof EntityItemFrame) {
if (!itemFrames.containsKey(event.getWorld())) {
itemFrames.put(event.getWorld(), new LinkedList<>());
}

itemFrames.get(event.getWorld()).add((EntityItemFrame) event.getEntity());
}
}

@SubscribeEvent
public void onWorldTick(TickEvent.WorldTickEvent event) {
if (event.phase == TickEvent.Phase.END && !event.world.isRemote) {
List<EntityItemFrame> list = itemFrames.get(event.world);
if (list != null) {
Iterator<EntityItemFrame> iterator = list.iterator();
while (iterator.hasNext()) {
EntityItemFrame frame = iterator.next();
if (frame.isDead) {
iterator.remove();
} else {
ItemStack stack = frame.getDisplayedItem();
if (stack.getItem() == InventoryNeko.itemNeko) {
// TODO: Add item frame logic proxying.
InventoryNeko.getOrCreateTagCompound(stack).setString("state", "sleep");
InventoryNeko.getOrCreateTagCompound(stack).setInteger("tick", 0);
}
}
}
}
}
}

@SubscribeEvent
public void onServerTick(TickEvent.ServerTickEvent event) {
if (event.phase == TickEvent.Phase.END) {

+ 49
- 0
src/main/java/pl/asie/inventoryneko/NekoVec2.java View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2017 Adrian Siekierka
*
* This file is part of InventoryNeko.
*
* InventoryNeko is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* InventoryNeko is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with InventoryNeko. If not, see <http://www.gnu.org/licenses/>.
*/

package pl.asie.inventoryneko;

public final class NekoVec2 {
public final int x, y;

public NekoVec2(int x, int y) {
this.x = x;
this.y = y;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof NekoVec2)) {
return false;
}

NekoVec2 other = (NekoVec2) o;
return other.x == x && other.y == y;
}

@Override
public int hashCode() {
return x * 17 + y;
}

@Override
public String toString() {
return "NekoVec2{" + x + "," + y + "}";
}
}

+ 9
- 20
src/main/java/pl/asie/inventoryneko/ProxyClient.java View File

@@ -40,20 +40,6 @@ public class ProxyClient extends ProxyCommon {
}


public void addTransformation(ImmutableMap.Builder<ItemCameraTransforms.TransformType, TRSRTransformation> transformMap, ItemCameraTransforms.TransformType type, TRSRTransformation transformation) {
transformMap.put(type, TRSRTransformation.blockCornerToCenter(transformation));
}

public void addThirdPersonTransformation(ImmutableMap.Builder<ItemCameraTransforms.TransformType, TRSRTransformation> transformMap, TRSRTransformation transformation) {
addTransformation(transformMap, ItemCameraTransforms.TransformType.THIRD_PERSON_RIGHT_HAND, transformation);
addTransformation(transformMap, ItemCameraTransforms.TransformType.THIRD_PERSON_LEFT_HAND, toLeftHand(transformation));
}

public void addFirstPersonTransformation(ImmutableMap.Builder<ItemCameraTransforms.TransformType, TRSRTransformation> transformMap, TRSRTransformation transformation) {
addTransformation(transformMap, ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND, transformation);
addTransformation(transformMap, ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND, toLeftHand(transformation));
}

private static final TRSRTransformation flipX = new TRSRTransformation(null, null, new Vector3f(-1, 1, 1), null);

private static TRSRTransformation toLeftHand(TRSRTransformation transform) {
@@ -69,14 +55,17 @@ public class ProxyClient extends ProxyCommon {
}

public ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> getDefaultItemTransforms() {
ImmutableMap.Builder<ItemCameraTransforms.TransformType, TRSRTransformation> transformMapBuilder = ImmutableMap.builder();
TRSRTransformation thirdperson = getTransformation(0, 3, 1, 0, 0, 0, 0.55f);
TRSRTransformation firstperson = getTransformation(1.13f, 3.2f, 1.13f, 0, -90, 25, 0.68f);
addTransformation(transformMapBuilder, ItemCameraTransforms.TransformType.GROUND, getTransformation(0, 2, 0, 0, 0, 0, 0.5f));
addTransformation(transformMapBuilder, ItemCameraTransforms.TransformType.HEAD, getTransformation(0, 13, 7, 0, 180, 0, 1));
addThirdPersonTransformation(transformMapBuilder, thirdperson);
addFirstPersonTransformation(transformMapBuilder, firstperson);
return transformMapBuilder.build();
ImmutableMap.Builder<ItemCameraTransforms.TransformType, TRSRTransformation> builder = ImmutableMap.builder();
builder.put(ItemCameraTransforms.TransformType.GROUND, getTransformation(0, 2, 0, 0, 0, 0, 0.5f));
builder.put(ItemCameraTransforms.TransformType.HEAD, getTransformation(0, 13, 7, 0, 180, 0, 1));
builder.put(ItemCameraTransforms.TransformType.THIRD_PERSON_RIGHT_HAND, thirdperson);
builder.put(ItemCameraTransforms.TransformType.THIRD_PERSON_LEFT_HAND, toLeftHand(thirdperson));
builder.put(ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND, firstperson);
builder.put(ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND, toLeftHand(firstperson));
builder.put(ItemCameraTransforms.TransformType.FIXED, getTransformation(0, 0, 0, 0, 180, 0, 1));
return builder.build();
}

@SubscribeEvent

Loading…
Cancel
Save