Skip to content

Commit 16b1426

Browse files
0.31 20100129 (0.31.20100129)
1 parent e03937d commit 16b1426

37 files changed

+342
-144
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ install:
1212
CYTHONIZE=1 pip install .
1313

1414
install-from-source: dist
15-
pip install dist/minecraft-python-0.31.20100128.tar.gz
15+
pip install dist/minecraft-python-0.31.20100129.tar.gz
1616

1717
clean:
1818
$(RM) -r build dist src/*.egg-info

README.md

+13-11
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
_**Minecraft: Python Edition**_ is a project that strives to recreate each and every old Minecraft version in Python 3 using the **Pyglet** multimedia library and **Cython** for performance.
66

77
The project is currently working on the Indev versions of Minecraft.
8-
The latest version is **Indev 0.31 20100128** as released on _**January 28, 2010**_.
8+
The latest version is **Indev 0.31 20100129** as released on _**January 29, 2010**_.
99

10-
This version adds diamonds, diamond ore, gears, metal tool variants, and semi-functional crafting to the game.
10+
This version adds functional crafting, sticks, the "Steve" and "Black Steve" MD3 mobs, and rudimentary smelting to the game.
11+
This is the first version where items must be gathered and crafted yourself, as opposed to them being provided in the chests at spawn.
1112

12-
Features from previous Indev versions include the Indev mossy cobblestone spawn house which contains chests
13-
with all of the items available in this version, NBT level file saving,
14-
tools including flint and steel and the bow and arrow, torches, advanced liquid spread, TNT explosives, and the MD3 Rana mobs.
13+
Features from previous Indev versions include the Indev mossy cobblestone spawn house, NBT level file saving,
14+
most tools, torches, advanced liquid spread, TNT explosives, and passive MD3 mobs.
1515

16-
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==0.31.20100128`.
16+
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==0.31.20100129`.
1717

18-
You can learn more about this version [on the Minecraft wiki.](https://minecraft.wiki/w/Java_Edition_Indev_0.31_20100128)
18+
You can learn more about this version [on the Minecraft wiki.](https://minecraft.wiki/w/Java_Edition_Indev_0.31_20100129)
1919

2020
### Organization
2121

@@ -42,21 +42,23 @@ The argument `-creative` will force the game to be in creative mode.
4242

4343
### Gameplay
4444

45-
All available tools and blocks are in the chests in the spawn house.
4645
All controls are as you would expect for the game and they can be configured in the options menu.
47-
Press I to open your inventory, B to craft (only recipe is an apple in the top-left corner for an arrow),
46+
Press I to open your inventory, B to craft (I to exit the crafting screen),
4847
F5 to toggle rain and F7 to take a cool isometric screenshot.
4948

49+
Smelting is unique in early Indev: to get iron or gold ingots, light the dropped ores on fire or throw them in lava.
50+
5051
The Indev level generator is customizable and you can choose between the *Inland*, *Island*, *Floating*, and *Flat* level types.
5152
You can specify the world theme as *Normal* or *Hell* (lava and dirt instead of water and grass), world size, and world shape (*Square*, *Long*, *Deep*).
5253

5354
Levels can be saved to a single *.mclevel* NBT file in the pause menu. The level files are perfectly compatible with Java and vice versa.
5455

55-
The only mobs around are the Ranas, but they don't drop anything when killed. Apples will restore health.
56+
The only mobs around are the Steves and Black Steves, which don't drop anything when killed.
57+
Apples will restore health.
5658

5759
![Isometric screenshot](/map.png?raw=true)
5860

59-
*An isometric screenshot of a deep Floating map generated by the game.*
61+
*An isometric screenshot of a normal Island map generated by the game, showing the MD3 mobs.*
6062

6163
### Additional Notes
6264

map.png

5 MB
Loading

mc/Resources.py

+3-1
Large diffs are not rendered by default.

mc/net/minecraft/client/Minecraft.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def displayGuiScreen(self, screen):
147147
if self.currentScreen or screen:
148148
self.screenChanged = True
149149
if self.currentScreen:
150-
self.currentScreen.onGuiClose()
150+
self.currentScreen.onGuiClosed()
151151

152152
if not screen and self.thePlayer.health <= 0:
153153
screen = GuiGameOver()

mc/net/minecraft/client/controller/PlayerControllerSP.py

+4-55
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,6 @@ def __init__(self, mc):
1616
self.__prevBlockDamage = 0
1717
self.__blockHitWait = 0
1818
self.__mobSpawner = None
19-
self.__mainChestArray = (
20-
blocks.stone, blocks.grass, blocks.cobblestone, blocks.planks, blocks.sapling,
21-
blocks.bedrock, blocks.sand, blocks.gravel, blocks.oreGold, blocks.oreIron,
22-
blocks.oreCoal, blocks.wood, blocks.leaves, blocks.sponge, blocks.glass,
23-
blocks.plantYellow, blocks.plantRed, blocks.mushroomBrown, blocks.mushroomRed,
24-
blocks.blockGold, blocks.blockSteel, blocks.stairSingle, blocks.brick, blocks.tnt,
25-
blocks.bookShelf, blocks.cobblestoneMossy, blocks.obsidian, blocks.torch,
26-
blocks.waterSource, blocks.lavaSource, blocks.chest
27-
)
28-
self.__woolChestArray = (
29-
blocks.clothRed, blocks.clothOrange, blocks.clothYellow,
30-
blocks.clothChartreuse, blocks.clothGreen, blocks.clothSpringGreen,
31-
blocks.clothCyan, blocks.clothCapri, blocks.clothUltramarine,
32-
blocks.clothViolet, blocks.clothPurple, blocks.clothMagenta,
33-
blocks.clothRose, blocks.clothDarkGray, blocks.clothGray, blocks.clothWhite
34-
)
3519

3620
def flipPlayer(self, player):
3721
x = int(player.posX)
@@ -53,47 +37,12 @@ def flipPlayer(self, player):
5337
self._mc.theWorld.setBlockWithNotify(xx, yy, zz, blockId)
5438

5539
self._mc.theWorld.setBlockWithNotify(x - 2, y - 1, z - 2, blocks.chest.blockID)
56-
itemsChest = self._mc.theWorld.getBlockTileEntity(x - 2, y - 1, z - 2)
40+
self._mc.theWorld.getBlockTileEntity(x - 2, y - 1, z - 2)
5741
self._mc.theWorld.setBlockWithNotify(x + 2, y - 1, z - 2, blocks.chest.blockID)
58-
blocksChest1 = self._mc.theWorld.getBlockTileEntity(x + 2, y - 1, z - 2)
42+
self._mc.theWorld.getBlockTileEntity(x + 2, y - 1, z - 2)
5943
self._mc.theWorld.setBlockWithNotify(x + 2, y - 1, z - 1, blocks.chest.blockID)
60-
blocksChest2 = self._mc.theWorld.getBlockTileEntity(x + 2, y - 1, z - 1)
61-
self._mc.theWorld.setBlockWithNotify(x - 1, y - 1, z + 2, blocks.chest.blockID)
62-
tntChest1 = self._mc.theWorld.getBlockTileEntity(x - 1, y - 1, z + 2)
63-
self._mc.theWorld.setBlockWithNotify(x, y - 1, z + 2, blocks.chest.blockID)
64-
tntChest2 = self._mc.theWorld.getBlockTileEntity(x, y - 1, z + 2)
65-
self._mc.theWorld.setBlockWithNotify(x + 2, y - 1, z + 1, blocks.chest.blockID)
66-
woolChest = self._mc.theWorld.getBlockTileEntity(x + 2, y - 1, z + 1)
67-
slot = 0
68-
for i in range(256, 1024):
69-
if items.itemsList[i]:
70-
limit = items.itemsList[i].getItemStackLimit()
71-
itemsChest.setInventorySlotContents(slot, ItemStack(i, limit))
72-
slot += 1
73-
if slot >= 27:
74-
break
75-
76-
for slot in range(27):
77-
blockId = blocks.tnt.blockID
78-
stack = ItemStack(blockId, items.itemsList[blockId].getItemStackLimit())
79-
tntChest1.setInventorySlotContents(slot, stack)
80-
stack = ItemStack(blockId, items.itemsList[blockId].getItemStackLimit())
81-
tntChest2.setInventorySlotContents(slot, stack)
82-
83-
for slot in range(min(len(self.__mainChestArray), 54)):
84-
blockId = self.__mainChestArray[slot]
85-
stack = ItemStack(blockId, items.itemsList[blockId.blockID].getItemStackLimit())
86-
if slot >= 27:
87-
blocksChest2.setInventorySlotContents(slot - 27, stack)
88-
else:
89-
blocksChest1.setInventorySlotContents(slot, stack)
90-
91-
for slot in range(min(len(self.__woolChestArray), 54)):
92-
stack = ItemStack(
93-
self.__woolChestArray[slot],
94-
items.itemsList[self.__woolChestArray[slot].blockID].getItemStackLimit()
95-
)
96-
woolChest.setInventorySlotContents(slot, stack)
44+
self._mc.theWorld.getBlockTileEntity(x + 2, y - 1, z - 1)
45+
player.inventory.mainInventory[8] = ItemStack(items.flintSteel)
9746

9847
def sendBlockRemoved(self, x, y, z):
9948
block = self._mc.theWorld.getBlockId(x, y, z)

mc/net/minecraft/client/gui/GuiCrafting.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def onCraftMatrixChanged(self):
4242
else:
4343
items[slot] = -1
4444

45-
self.__iInventory.setInventorySlotContents(0, CraftingManager.addRecipe(items))
45+
self.__iInventory.setInventorySlotContents(0, CraftingManager.getInstance().addRecipe(items))
4646

4747
def _drawGuiContainerForegroundLayer(self):
4848
self._fontRenderer.drawString('Crafting', 8, 6, 4210752)

mc/net/minecraft/client/gui/GuiScreen.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ def handleKeyboardEvent(self, key=None, char=None, motion=None):
4646
def updateScreen(self):
4747
pass
4848

49-
def onGuiClose(self):
49+
def onGuiClosed(self):
5050
pass

mc/net/minecraft/client/gui/InventoryCraftResult.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from mc.net.minecraft.game.Inventory import Inventory
22

33
class InventoryCraftResult(Inventory):
4-
STACK_LIMIT = 100
4+
STACK_LIMIT = 64
55

66
def __init__(self, eventHandler):
77
self.__stackResult = [None]

mc/net/minecraft/client/gui/InventoryCrafting.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from mc.net.minecraft.game.Inventory import Inventory
22

33
class InventoryCrafting(Inventory):
4-
STACK_LIMIT = 100
4+
STACK_LIMIT = 64
55

66
def __init__(self, eventHandler):
77
self.__eventHandler = eventHandler
@@ -16,6 +16,23 @@ def getStackInSlot(self, slot):
1616
def getInvName(self):
1717
return 'Crafting'
1818

19+
def decrStackSize(self, slot, size):
20+
if not self.stackList[slot]:
21+
return None
22+
23+
if self.stackList[slot].stackSize <= 1:
24+
stack = self.stackList[slot]
25+
self.stackList[slot] = None
26+
self.__eventHandler.onCraftMatrixChanged()
27+
return stack
28+
else:
29+
stack = self.stackList[slot].splitStack(1)
30+
if self.stackList[slot].stackSize == 0:
31+
self.stackList[slot] = None
32+
33+
self.__eventHandler.onCraftMatrixChanged()
34+
return stack
35+
1936
def setInventorySlotContents(self, slot, stack):
2037
self.stackList[slot] = stack
2138
self.__eventHandler.onCraftMatrixChanged()

mc/net/minecraft/client/gui/SlotCrafting.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ def isItemValid(self):
1111

1212
def onPickupFromSlot(self):
1313
for slot in range(9):
14-
self.__craftMatrix.inventoryCrafting.setInventorySlotContents(slot, None)
14+
if self.__craftMatrix.inventoryCrafting.getStackInSlot(slot):
15+
self.__craftMatrix.inventoryCrafting.decrStackSize(slot, 1)

mc/net/minecraft/client/model/md3/MD3Loader.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,6 @@ def __loadMD3Info(buffer, size):
159159

160160
for i in range(len(b)):
161161
if b[i] == 0:
162-
return b[:i].decode('utf-8')
162+
return b[:i].decode('utf-8', errors='ignore')
163163

164-
return b.decode('utf-8')
164+
return b.decode('utf-8', errors='ignore')

mc/net/minecraft/client/model/md3/MD3Model.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ def __init__(self, vertices):
88
self.__vertices = vertices
99
self.__displayList = 0
1010

11-
def renderModelVertices(self):
11+
def getFrames(self):
12+
return self.__vertices.totalFrames
13+
14+
def renderModelVertices(self, a, _, ticks):
1215
if self.__displayList == 0:
1316
self.__displayList = gl.glGenLists(self.__vertices.totalFrames)
1417

@@ -35,4 +38,4 @@ def renderModelVertices(self):
3538
gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
3639
gl.glDisableClientState(gl.GL_NORMAL_ARRAY)
3740

38-
gl.glCallList(self.__displayList)
41+
gl.glCallList(self.__displayList + a)

mc/net/minecraft/client/render/entity/RenderMD3.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ def __init__(self):
1111
self._shadowSize = 0.5
1212

1313
try:
14-
self.__model[0] = MD3Model((MD3Loader()).loadModel('test2.md3'))
14+
self.__model[0] = MD3Model((MD3Loader()).loadModel('mcexport01.MD3'))
15+
print('Animation frames:', self.__model[0].getFrames())
1516
except IOError as e:
1617
print(e)
1718

@@ -21,12 +22,20 @@ def doRender(self, entity, xd, yd, zd, yaw, a):
2122
try:
2223
zo = entity.prevRenderYawOffset + (entity.renderYawOffset - entity.prevRenderYawOffset) * a
2324
gl.glTranslatef(xd, yd, zd)
24-
self._loadTexture('cube-nes.png')
25+
if entity.mobType == 0:
26+
self._loadTexture('mcexport2.png')
27+
elif entity.mobType == 1:
28+
self._loadTexture('mcexport.png')
29+
2530
gl.glRotatef(-zo + 180.0, 0.0, 1.0, 0.0)
2631
gl.glRotatef(-90.0, 1.0, 0.0, 0.0)
2732
gl.glScalef(0.02, -0.02, 0.02)
33+
ticks = (entity.ticksExisted + a) * entity.randVal
34+
a = int(ticks) % self.__model[0].getFrames()
35+
_ = (a + 1) % self.__model[0].getFrames()
36+
ticks -= int(ticks)
2837
gl.glEnable(gl.GL_NORMALIZE)
29-
self.__model[0].renderModelVertices()
38+
self.__model[0].renderModelVertices(a, _, ticks)
3039
gl.glDisable(gl.GL_NORMALIZE)
3140
except Exception as e:
3241
print(e)

mc/net/minecraft/game/entity/Entity.pyx

+4-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ cdef class Entity:
286286
self.__ySize *= 0.4
287287
inWater = self.handleWaterMovement()
288288
if self._worldObj.isBoundingBoxBurning(self.boundingBox):
289-
self.attackEntityFrom(None, 1)
289+
self._hurt(1)
290290
if not inWater:
291291
self.fire += 1
292292
if self.fire == 0:
@@ -301,6 +301,9 @@ cdef class Entity:
301301
)
302302
self.fire = -self.fireResistance
303303

304+
def _hurt(self, int hp):
305+
self.attackEntityFrom(None, 1)
306+
304307
cdef _fall(self, float distance):
305308
pass
306309

mc/net/minecraft/game/entity/EntityLiving.pxd

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ cdef class EntityLiving(Entity):
2121
public float prevCameraPitch
2222
public float cameraPitch
2323
public AILiving _entityAI
24+
public float randVal
25+
public int mobType
2426

2527
cdef _fall(self, float d)
2628
cdef travel(self, float x, float z)

mc/net/minecraft/game/entity/EntityLiving.pyx

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ cdef class EntityLiving(Entity):
3737
self.setPosition(self.posX, self.posY, self.posZ)
3838
self.rotationYaw = random() * (pi * 2.0)
3939
self.stepHeight = 0.5
40+
self.randVal = random() * 0.9 + 0.1
41+
self.mobType = self._rand.nextInt(2)
4042

4143
def canBeCollidedWith(self):
4244
return not self.isDead

mc/net/minecraft/game/entity/misc/EntityItem.py

+8
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ def onEntityUpdate(self):
9797
if self.age >= 6000:
9898
self.setEntityDead()
9999

100+
def _hurt(self, hp):
101+
if self.item.getItem().onPlaced(self._worldObj, self.posX,
102+
self.posY, self.posZ):
103+
self.item.stackSize = 0
104+
105+
if self.item.stackSize == 0:
106+
self.setEntityDead()
107+
100108
def attackEntityFrom(self, entity, damage):
101109
self.__health -= damage
102110
if self.__health <= 0:

mc/net/minecraft/game/entity/player/InventoryPlayer.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from mc.net.minecraft.game.Inventory import Inventory
44

55
class InventoryPlayer(Inventory):
6-
PLAYER_STACK_LIMIT = 50
6+
PLAYER_STACK_LIMIT = 64
77

88
def __init__(self):
99
self.currentItem = 0
@@ -73,7 +73,7 @@ def storePartialItemStack(self, stack):
7373
if self.mainInventory[maybeSlot] and self.mainInventory[maybeSlot].itemID == itemId:
7474
item = self.mainInventory[maybeSlot]
7575
if self.mainInventory[maybeSlot].stackSize < item.getItem().getItemStackLimit() and \
76-
self.mainInventory[maybeSlot].stackSize < 50:
76+
self.mainInventory[maybeSlot].stackSize < InventoryPlayer.PLAYER_STACK_LIMIT:
7777
slot = maybeSlot
7878
break
7979

@@ -92,7 +92,10 @@ def storePartialItemStack(self, stack):
9292
item = self.mainInventory[slot]
9393
stackExcess = item.getItem().getItemStackLimit() - self.mainInventory[slot].stackSize
9494

95-
stackExcess = min(stackExcess, 50 - self.mainInventory[slot].stackSize)
95+
stackExcess = min(
96+
stackExcess,
97+
InventoryPlayer.PLAYER_STACK_LIMIT - self.mainInventory[slot].stackSize
98+
)
9699
if stackExcess == 0:
97100
stackSize = stackSize
98101
else:

mc/net/minecraft/game/entity/projectile/EntityArrow.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from mc.net.minecraft.game.entity.Entity import Entity
2-
from mc.net.minecraft.game.item.ItemStack import ItemStack
32
from mc.net.minecraft.game.physics.Vec3D import Vec3D
43

54
from nbtlib.tag import Short, Byte
@@ -132,6 +131,7 @@ def _getEntityString(self):
132131

133132
def onCollideWithPlayer(self, player):
134133
from mc.net.minecraft.game.item.Items import items
134+
from mc.net.minecraft.game.item.ItemStack import ItemStack
135135
if self.__inGround and self.__owner == player and self.arrowShake <= 0 and \
136136
player.inventory.storePartialItemStack(ItemStack(items.arrow.shiftedIndex, 1)):
137137
self.setEntityDead()

mc/net/minecraft/game/item/Item.py

+3
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ def onItemRightClick(self, stack, world, player):
2525

2626
def getItemStackLimit(self):
2727
return self._maxStackSize
28+
29+
def onPlaced(self, world, x, y, z):
30+
return False

mc/net/minecraft/game/item/ItemBlock.py

+3
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ def onItemUse(self, stack, world, x, y, z, sideHit):
4040
volume = (block.stepSound.soundVolume + 1.0) / 2.0
4141
world.playSoundEffect(x, y, z, name, volume, block.stepSound.soundPitch * 0.8)
4242
stack.stackSize -= 1
43+
44+
def onPlaced(self, world, x, y, z):
45+
return blocks.blocksList[self.__blockID].oreDrop(world, x, y, z)

0 commit comments

Comments
 (0)