Skip to content
This repository was archived by the owner on Jan 3, 2020. It is now read-only.

Commit 3394715

Browse files
committed
1.8
1 parent efb22eb commit 3394715

File tree

5 files changed

+352
-6
lines changed

5 files changed

+352
-6
lines changed

.gitignore

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
*
2-
!build.gradle
3-
!.gitignore
4-
!src
5-
!LICENSE
6-
!README
1+
*.iml
2+
build/
3+
.gradle
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package org.devinprogress.autoharvest;
2+
3+
import net.minecraft.block.Block;
4+
import net.minecraft.block.state.IBlockState;
5+
import net.minecraft.init.Blocks;
6+
import net.minecraft.init.Items;
7+
import net.minecraft.item.Item;
8+
import net.minecraft.item.ItemStack;
9+
import net.minecraft.util.BlockPos;
10+
import net.minecraft.world.World;
11+
12+
import java.util.HashMap;
13+
import java.util.HashSet;
14+
import java.util.Map;
15+
import java.util.Set;
16+
17+
public class CropManager {
18+
public static final Block REED_BLOCK = Block.getBlockFromName("reeds");
19+
public static final Block FARMLAND = Blocks.farmland;
20+
public static final Block NETHER_WART = Blocks.nether_wart;
21+
22+
23+
public static final Set<Block> WEED_BLOCKS = new HashSet<Block>() {{
24+
add(Block.getBlockFromName("sapling"));
25+
add(Block.getBlockFromName("tallgrass"));
26+
add(Block.getBlockFromName("deadbush"));
27+
add(Block.getBlockFromName("yellow_flower"));
28+
add(Block.getBlockFromName("red_flower"));
29+
add(Block.getBlockFromName("brown_mushroom"));
30+
add(Block.getBlockFromName("red_mushroom"));
31+
add(Block.getBlockFromName("double_plant"));
32+
add(Blocks.fire);
33+
}};
34+
35+
public static final Map<Block, Item> CROP_BLOCKS = new HashMap<Block, Item>() {{
36+
put(Block.getBlockFromName("wheat"), Item.getByNameOrId("wheat_seeds"));
37+
put(Blocks.potatoes, Items.potato);
38+
put(Blocks.carrots, Items.carrot);
39+
}};
40+
41+
public static final Set<Item> SEED_ITEMS = new HashSet<Item>() {{
42+
add(Items.wheat_seeds);
43+
add(Items.potato);
44+
add(Items.carrot);
45+
add(Items.nether_wart);
46+
add(Items.reeds);
47+
}};
48+
49+
public static boolean isWeedBlock(World w, BlockPos pos) {
50+
Block b = w.getBlockState(pos).getBlock();
51+
return WEED_BLOCKS.contains(b);
52+
}
53+
54+
public static boolean isCropMature(World w, BlockPos pos, IBlockState stat, Block b) {
55+
if (CROP_BLOCKS.containsKey(b)) {
56+
return b.getMetaFromState(stat) >= 7;
57+
} else if (b == NETHER_WART) {
58+
return b.getMetaFromState(stat) >= 3;
59+
} else if (b == REED_BLOCK) {
60+
if (w.getBlockState(pos.down()).getBlock() != REED_BLOCK
61+
&& w.getBlockState(pos.up()).getBlock() == REED_BLOCK) {
62+
return true;
63+
} else {
64+
return false;
65+
}
66+
}
67+
return false;
68+
}
69+
70+
public static Item getSeedItem(Block b) {
71+
if (CROP_BLOCKS.containsKey(b)) {
72+
return CROP_BLOCKS.get(b);
73+
} else if (b == NETHER_WART) {
74+
return Items.nether_wart;
75+
} else {
76+
return null;
77+
}
78+
}
79+
80+
public static boolean isSeed(ItemStack stack) {
81+
if (stack == null || stack.stackSize <= 0) return false;
82+
return SEED_ITEMS.contains(stack.getItem());
83+
}
84+
85+
public static boolean canPlantOn(Item m, World w, BlockPos p, Block b) {
86+
if (m == Items.nether_wart) {
87+
return b == Blocks.soul_sand;
88+
} else if (m == Items.reeds) {
89+
return b == Blocks.sand || b == Blocks.grass || b == Blocks.dirt;
90+
} else {
91+
return b == FARMLAND;
92+
}
93+
}
94+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.devinprogress.autoharvest;
2+
3+
import net.minecraft.client.settings.KeyBinding;
4+
import net.minecraftforge.fml.client.registry.ClientRegistry;
5+
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
6+
import net.minecraftforge.fml.common.gameevent.InputEvent;
7+
import org.lwjgl.input.Keyboard;
8+
9+
public class KeyPressListener {
10+
public static final KeyBinding toggleKey = new KeyBinding("key.toggleAutoharvest", Keyboard.KEY_H, "key.categories.misc");
11+
12+
public KeyPressListener() {
13+
ClientRegistry.registerKeyBinding(toggleKey);
14+
}
15+
16+
@SubscribeEvent
17+
public void onKeyPressed(InputEvent.KeyInputEvent event) {
18+
if (toggleKey.isPressed()) {
19+
AutoHarvest a = AutoHarvest.instance;
20+
String modeName = a.toNextMode().toString().toLowerCase();
21+
AutoHarvest.sendI18nMsg("notify.switch_to." + modeName);
22+
}
23+
}
24+
}
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package org.devinprogress.autoharvest;
2+
3+
import net.minecraft.block.Block;
4+
import net.minecraft.block.state.IBlockState;
5+
import net.minecraft.client.Minecraft;
6+
import net.minecraft.entity.Entity;
7+
import net.minecraft.entity.monster.EntityZombie;
8+
import net.minecraft.entity.passive.*;
9+
import net.minecraft.entity.player.EntityPlayer;
10+
import net.minecraft.entity.player.InventoryPlayer;
11+
import net.minecraft.init.Blocks;
12+
import net.minecraft.init.Items;
13+
import net.minecraft.item.Item;
14+
import net.minecraft.item.ItemStack;
15+
import net.minecraft.util.AxisAlignedBB;
16+
import net.minecraft.util.BlockPos;
17+
import net.minecraft.util.EnumFacing;
18+
import net.minecraft.util.Vec3;
19+
import net.minecraft.world.World;
20+
import net.minecraftforge.fml.client.FMLClientHandler;
21+
import net.minecraftforge.fml.common.FMLCommonHandler;
22+
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
23+
import net.minecraftforge.fml.common.gameevent.TickEvent;
24+
import net.minecraftforge.fml.relauncher.Side;
25+
26+
import java.util.HashMap;
27+
import java.util.List;
28+
import java.util.Map;
29+
30+
public class TickListener {
31+
private int tickCount = 0;
32+
private static final int tickRate = 2;
33+
private static final int seedRange = 3;
34+
private static final int harvestRange = 2;
35+
private final AutoHarvest.HarvestMode mode;
36+
37+
public TickListener(AutoHarvest.HarvestMode mode) {
38+
this.mode = mode;
39+
}
40+
41+
@SuppressWarnings("unused")
42+
@SubscribeEvent
43+
public void onTick(TickEvent.PlayerTickEvent e) {
44+
if (e.side == Side.CLIENT && e.player != null &&
45+
e.player == FMLClientHandler.instance().getClientPlayerEntity()) {
46+
if ((++tickCount) == tickRate) {
47+
tickCount = 0;
48+
switch (mode) {
49+
case SEED: {
50+
seedTick(e.player);
51+
break;
52+
}
53+
case EAGER: {
54+
harvestTick(e.player);
55+
break;
56+
}
57+
case PLANT: {
58+
plantTick(e.player);
59+
break;
60+
}
61+
case FEED: {
62+
feedTick(e.player);
63+
break;
64+
}
65+
// case ATTACK: {
66+
// attackTick(e.player);
67+
// break;
68+
// }
69+
}
70+
}
71+
}
72+
}
73+
74+
private void seedTick(EntityPlayer p) {
75+
World w = p.worldObj;
76+
int X = (int) Math.floor(p.posX);
77+
int Y = (int) Math.floor(p.posY);//the "leg block"
78+
int Z = (int) Math.floor(p.posZ);
79+
for (int deltaY = 1; deltaY >= -1; --deltaY)
80+
for (int deltaX = -seedRange; deltaX <= seedRange; ++deltaX)
81+
for (int deltaZ = -seedRange; deltaZ <= seedRange; ++deltaZ) {
82+
BlockPos pos = new BlockPos(X + deltaX, Y + deltaY, Z + deltaZ);
83+
if (CropManager.isWeedBlock(w, pos)) {
84+
Minecraft.getMinecraft().playerController.onPlayerDamageBlock(pos, EnumFacing.UP);
85+
return;
86+
}
87+
}
88+
}
89+
90+
private void harvestTick(EntityPlayer p) {
91+
World w = p.worldObj;
92+
int X = (int) Math.floor(p.posX);
93+
int Y = (int) Math.floor(p.posY + 0.2D);//the "leg block", in case in soul sand
94+
int Z = (int) Math.floor(p.posZ);
95+
for (int deltaX = -harvestRange; deltaX <= harvestRange; ++deltaX)
96+
for (int deltaZ = -harvestRange; deltaZ <= harvestRange; ++deltaZ) {
97+
BlockPos pos = new BlockPos(X + deltaX, Y, Z + deltaZ);
98+
IBlockState state = w.getBlockState(pos);
99+
Block b = state.getBlock();
100+
if (CropManager.isCropMature(w, pos, state, b)) {
101+
if (b == Blocks.reeds) pos = pos.up();
102+
Minecraft.getMinecraft().playerController.onPlayerDamageBlock(pos, EnumFacing.UP);
103+
return;
104+
}
105+
}
106+
}
107+
108+
private static final int REFILL_THRESHOLD = 2;
109+
110+
private boolean tryFillItemInHand(EntityPlayer p) {
111+
InventoryPlayer inv = p.inventory;
112+
ItemStack itemStack = inv.getCurrentItem();
113+
if (itemStack == null || itemStack.stackSize > REFILL_THRESHOLD) return false;
114+
Class<? extends Item> targetItemClass = itemStack.getItem().getClass();
115+
116+
for (int i = 0; i < 9; i++) {
117+
if (inv.getStackInSlot(i) == null) continue;
118+
if (inv.getStackInSlot(i).getItem().getClass().equals(targetItemClass) && inv.getStackInSlot(i).stackSize > REFILL_THRESHOLD) {
119+
while (i < inv.currentItem) inv.changeCurrentItem(1);
120+
while (i > inv.currentItem) inv.changeCurrentItem(-1);
121+
return true;
122+
}
123+
}
124+
AutoHarvest.sendI18nMsg("notify.lack_of_seed");
125+
AutoHarvest.sendI18nMsg("notify.switch_to.off");
126+
AutoHarvest.instance.toNextMode(AutoHarvest.HarvestMode.OFF);
127+
128+
return false;
129+
}
130+
131+
private void plantTick(EntityPlayer p) {
132+
ItemStack handItem = p.getHeldItem();
133+
if (!CropManager.isSeed(handItem)) {
134+
return;
135+
}
136+
137+
World w = p.worldObj;
138+
int X = (int) Math.floor(p.posX);
139+
int Y = (int) Math.floor(p.posY + 0.2D);//the "leg block" , in case in soul sand
140+
int Z = (int) Math.floor(p.posZ);
141+
142+
for (int deltaX = -harvestRange; deltaX <= harvestRange; ++deltaX)
143+
for (int deltaZ = -harvestRange; deltaZ <= harvestRange; ++deltaZ) {
144+
BlockPos pos = new BlockPos(X + deltaX, Y, Z + deltaZ);
145+
BlockPos downPos = pos.down();
146+
Block downBlock = w.getBlockState(downPos).getBlock();
147+
if (w.getBlockState(pos).getBlock() == Blocks.air
148+
&& downBlock != Blocks.air
149+
&& CropManager.canPlantOn(handItem.getItem(), w, downPos, downBlock)) {
150+
if (handItem.stackSize <= REFILL_THRESHOLD && tryFillItemInHand(p))
151+
handItem = p.getHeldItem();
152+
FMLClientHandler.instance().getClient().playerController.onPlayerRightClick(
153+
FMLClientHandler.instance().getClientPlayerEntity(),
154+
FMLClientHandler.instance().getWorldClient(),
155+
handItem, downPos, EnumFacing.UP,
156+
new Vec3(X + deltaX + 0.5, Y, Z + deltaZ + 0.5));
157+
}
158+
}
159+
}
160+
161+
private boolean tryFeedAnimal(Class<? extends EntityAnimal> type, AxisAlignedBB box, EntityPlayer p) {
162+
for (EntityAnimal e : (List<EntityAnimal>) (p.getEntityWorld().getEntitiesWithinAABB(type, box))) {
163+
if (e.getGrowingAge() == 0 && !e.isInLove()) {
164+
FMLClientHandler.instance().getClient().playerController.interactWithEntitySendPacket(p, e);
165+
return true;
166+
}
167+
}
168+
return false;
169+
}
170+
171+
private void feedTick(EntityPlayer p) {
172+
ItemStack handItem = p.getHeldItem();
173+
if (handItem == null) return;
174+
if (handItem.getItem().equals(Items.carrot)) { //pig & rabbit
175+
if (handItem.stackSize <= REFILL_THRESHOLD) tryFillItemInHand(p);
176+
AxisAlignedBB box = AxisAlignedBB.fromBounds(p.posX - 2, p.posY - 1, p.posZ - 2, p.posX + 2, p.posY + 3, p.posZ + 2);
177+
if (tryFeedAnimal(EntityPig.class, box, p)) return;
178+
if (tryFeedAnimal(EntityRabbit.class, box, p)) return;
179+
} else if (handItem.getItem().equals(Items.wheat)) { //cow & sheep & mooshrom
180+
if (handItem.stackSize <= REFILL_THRESHOLD) tryFillItemInHand(p);
181+
AxisAlignedBB box = AxisAlignedBB.fromBounds(p.posX - 2, p.posY - 1, p.posZ - 2, p.posX + 2, p.posY + 3, p.posZ + 2);
182+
if (tryFeedAnimal(EntityCow.class, box, p)) return;
183+
if (tryFeedAnimal(EntityMooshroom.class, box, p)) return;
184+
if (tryFeedAnimal(EntitySheep.class, box, p)) return;
185+
} else if (handItem.getItem().equals(Items.wheat_seeds)) { //chicken
186+
if (handItem.stackSize <= REFILL_THRESHOLD) tryFillItemInHand(p);
187+
AxisAlignedBB box = AxisAlignedBB.fromBounds(p.posX - 2, p.posY - 1, p.posZ - 2, p.posX + 2, p.posY + 3, p.posZ + 2);
188+
if (tryFeedAnimal(EntityChicken.class, box, p)) return;
189+
} else if (handItem.getItem().equals(Items.shears)) { // wool
190+
AxisAlignedBB box = AxisAlignedBB.fromBounds(p.posX - 2, p.posY - 1, p.posZ - 2, p.posX + 2, p.posY + 3, p.posZ + 2);
191+
for (EntitySheep e : (List<EntitySheep>) (p.getEntityWorld().getEntitiesWithinAABB(EntitySheep.class, box))) {
192+
if (!e.isChild() && !e.getSheared()) {
193+
FMLClientHandler.instance().getClient().playerController.interactWithEntitySendPacket(p, e);
194+
return;
195+
}
196+
}
197+
}
198+
}
199+
200+
private long gameTick = 0;
201+
private static final int ATTACK_GAP = 5;
202+
private Map<Entity, Long> attackTime = new HashMap<Entity, Long>();
203+
204+
private void attackTick(EntityPlayer p) {
205+
gameTick += tickRate;
206+
AxisAlignedBB box = AxisAlignedBB.fromBounds(p.posX - 2, p.posY - 2, p.posZ - 2, p.posX + 2, p.posY + 3, p.posZ + 2);
207+
List<Entity> aroundMobs = p.getEntityWorld().getEntitiesWithinAABB(EntityZombie.class, box);
208+
for (Entity e : aroundMobs) {
209+
Long t = attackTime.get(e);
210+
if (t == null || t < gameTick) {
211+
FMLClientHandler.instance().getClient().playerController.attackEntity(p, e);
212+
attackTime.put(e, gameTick);
213+
return;
214+
}
215+
}
216+
}
217+
218+
public void self_stop() {
219+
// CLEANUP
220+
FMLCommonHandler.instance().bus().unregister(this);
221+
}
222+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
key.toggleAutoharvest=切换自动收割状态
2+
notify.switch_to.eager=已切换到 收割 模式
3+
notify.switch_to.plant=已切换到 种植 模式
4+
notify.switch_to.smart=已切换到 自动 模式
5+
notify.switch_to.seed=已切换到 除草 模式
6+
notify.switch_to.feed=已切换到 喂食 模式
7+
notify.switch_to.attack=已切换到 攻击 模式
8+
notify.switch_to.off=自动收割 已关闭
9+
notify.lack_of_seed=缺少种子

0 commit comments

Comments
 (0)