Skip to content

Commit aa71f70

Browse files
0.31 20100131 (0.31.20100131)
1 parent 7e04ea4 commit aa71f70

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+955
-813
lines changed

MANIFEST.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ graft mc/resources/icon
99
include LICENSE
1010
include README.md
1111

12-
recursive-include mc *.pyx *.pxd *.ogg *.md3 *.MD3 *.dll
12+
recursive-include mc *.pyx *.pxd *.ogg *.dll
1313
recursive-exclude mc/resources/texture *
1414
recursive-exclude * *.pyc
1515
recursive-exclude * *.pyd

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.20100130.tar.gz
15+
pip install dist/minecraft-python-0.31.20100131.tar.gz
1616

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

README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
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 20100130** as released on _**January 30, 2010**_.
8+
The latest version is **Indev 0.31 20100131** as released on _**January 31, 2010**_.
99

10-
This version adds workbench crafting, gold tools, the "Beast Boy" MD3 mob, mob item drops, and soup to the game.
10+
This version adds the main menu, passive human mobs, and item durability to the game.
1111

1212
Features from previous Indev versions include the Indev mossy cobblestone spawn house, NBT level file saving,
13-
tools, torches, advanced liquid spread, TNT explosives, chests, and passive MD3 mobs.
13+
tools, torches, advanced liquid spread, TNT explosives, chests, workbench crafting, and soup.
1414

15-
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==0.31.20100130`.
15+
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==0.31.20100131`.
1616

17-
You can learn more about this version [on the Minecraft wiki.](https://minecraft.wiki/w/Java_Edition_Indev_0.31_20100130)
17+
You can learn more about this version [on the Minecraft wiki.](https://minecraft.wiki/w/Java_Edition_Indev_0.31_20100131)
1818

1919
### Organization
2020

@@ -51,13 +51,13 @@ You can specify the world theme as *Normal* or *Hell* (lava and dirt instead of
5151

5252
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.
5353

54-
MD3 Steves may drop string on death, Black Steves may drop gunpowder, and Beast Boys may drop feathers.
54+
Humans may drop string on death, gunpowder, or feathers upon death.
5555

5656
Crafted mushroom bowl soup will restore health. Check the Wiki for crafting recipes added in this version.
5757

5858
![Isometric screenshot](/map.png?raw=true)
5959

60-
*An isometric screenshot of a normal Island map generated by the game, showing the MD3 mobs.*
60+
*An isometric screenshot of a normal Island map generated by the game, with several spawn houses from map loading.*
6161

6262
### Additional Notes
6363

@@ -66,3 +66,5 @@ the textures are only there for convenience, as all of the texture buffers are a
6666
in the `mc.Resources` module.
6767

6868
This would have been much more challenging to work on without the great tools provided by [RetroMCP-Java](https://github.com/MCPHackers/RetroMCP-Java).
69+
70+
All credit for Minecraft goes towards its creator Notch and Mojang Specifications.

map.png

1.53 MB
Loading

mc/Resources.py

+1
Large diffs are not rendered by default.
+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from mc.net.minecraft.client.gui.GuiScreen import GuiScreen
2+
from mc.net.minecraft.client.gui.GuiOptions import GuiOptions
3+
from mc.net.minecraft.client.gui.GuiNewLevel import GuiNewLevel
4+
from mc.net.minecraft.client.gui.GuiLoadLevel import GuiLoadLevel
5+
from mc.net.minecraft.client.gui.GuiButton import GuiButton
6+
from mc.net.minecraft.client.render.Tessellator import tessellator
7+
from mc.JavaUtils import getMillis
8+
from pyglet import gl
9+
10+
import math
11+
12+
class GuiMainTitle(GuiScreen):
13+
14+
def __init__(self):
15+
self.__updateCounter = 0.0
16+
17+
def updateScreen(self):
18+
self.__updateCounter += 0.01
19+
20+
def _keyTyped(self, key, char, motion):
21+
pass
22+
23+
def initGui(self):
24+
self._controlList.clear()
25+
self._controlList.append(GuiButton(1, self.width // 2 - 100,
26+
self.height // 4 + 48, 'Generate new level...'))
27+
self._controlList.append(GuiButton(2, self.width // 2 - 100,
28+
self.height // 4 + 72, 'Load level..'))
29+
self._controlList.append(GuiButton(3, self.width // 2 - 100,
30+
self.height // 4 + 96, 'Play tutorial level'))
31+
self._controlList.append(GuiButton(0, self.width // 2 - 100,
32+
self.height // 4 + 120 + 12, 'Options...'))
33+
self._controlList[2].enabled = False
34+
if not self.mc.session:
35+
self._controlList[1].enabled = False
36+
37+
def _actionPerformed(self, button):
38+
if button.id == 0:
39+
self.mc.displayGuiScreen(GuiOptions(self, self.mc.options))
40+
elif button.id == 1:
41+
self.mc.displayGuiScreen(GuiNewLevel(self))
42+
elif self.mc.session and button.id == 2:
43+
self.mc.displayGuiScreen(GuiLoadLevel(self))
44+
45+
def drawScreen(self, xm, ym):
46+
gl.glDisable(gl.GL_LIGHTING)
47+
gl.glDisable(gl.GL_FOG)
48+
t = tessellator
49+
gl.glBindTexture(gl.GL_TEXTURE_2D, self.mc.renderEngine.getTexture('dirt.png'))
50+
gl.glColor4f(1.0, 1.0, 1.0, 1.0)
51+
t.startDrawingQuads()
52+
t.setColorOpaque_I(4210752)
53+
t.addVertexWithUV(0.0, self.height, 0.0, 0.0,
54+
self.height / 32.0 + self.__updateCounter)
55+
t.addVertexWithUV(self.width, self.height, 0.0, self.width / 32.0,
56+
self.height / 32.0 + self.__updateCounter)
57+
t.addVertexWithUV(self.width, 0.0, 0.0,
58+
self.width / 32.0, 0.0 + self.__updateCounter)
59+
t.addVertexWithUV(0.0, 0.0, 0.0, 0.0, 0.0 + self.__updateCounter)
60+
t.draw()
61+
gl.glBindTexture(gl.GL_TEXTURE_2D, self.mc.renderEngine.getTexture('gui/logo.png'))
62+
gl.glColor4f(1.0, 1.0, 1.0, 1.0)
63+
t.setColorOpaque_I(16777215)
64+
self.drawTexturedModalRect((self.width - 256) // 2, 30, 0, 0, 256, 49)
65+
gl.glPushMatrix()
66+
gl.glTranslatef(self.width / 2 + 90, 70.0, 0.0)
67+
gl.glRotatef(-20.0, 0.0, 0.0, 1.0)
68+
size = 1.8 - abs(math.sin((getMillis() % 1000) / 1000.0 * math.pi * 2.0) * 0.1)
69+
gl.glScalef(size, size, size)
70+
self.drawCenteredString(self._fontRenderer, 'Pre-beta!', 0, -8, 16776960)
71+
gl.glPopMatrix()
72+
copyright = 'Copyright Mojang Specifications. Do not distribute.'
73+
self.drawString(
74+
self._fontRenderer, copyright,
75+
self.width - self._fontRenderer.getStringWidth(copyright) - 2,
76+
self.height - 10, 16777215
77+
)
78+
super().drawScreen(xm, ym)

mc/net/minecraft/client/Minecraft.py

+25-8
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ def load_library(*names, **kwargs):
2727

2828
from mc.net.minecraft.client import MinecraftError
2929
from mc.net.minecraft.client.Timer import Timer
30+
from mc.net.minecraft.client.GuiMainTitle import GuiMainTitle
3031
from mc.net.minecraft.client.GameSettings import GameSettings
3132
from mc.net.minecraft.client.OpenGlCapsChecker import OpenGlCapsChecker
3233
from mc.net.minecraft.client.LoadingScreenRenderer import LoadingScreenRenderer
3334
from mc.net.minecraft.game.level.World import World
3435
from mc.net.minecraft.game.level.block.Blocks import blocks
36+
from mc.net.minecraft.game.item.Items import items
3537
from mc.net.minecraft.game.level.generator.LevelGenerator import LevelGenerator
38+
from mc.net.minecraft.game.entity.EntityLiving import EntityLiving
3639
from mc.net.minecraft.client.model.ModelBiped import ModelBiped
3740
from mc.net.minecraft.client.player.EntityPlayerSP import EntityPlayerSP
3841
from mc.net.minecraft.client.player.MovementInputFromOptions import MovementInputFromOptions
@@ -118,6 +121,7 @@ def __init__(self, fullscreen, creative, *args, **kwargs):
118121
self.objectMouseOver = None
119122
self.sndManager = SoundManager()
120123
self.__leftClickCounter = 0
124+
self.mcDataDir = ''
121125

122126
self.__serverIp = ''
123127

@@ -142,7 +146,9 @@ def displayGuiScreen(self, screen):
142146
if self.currentScreen:
143147
self.currentScreen.onGuiClosed()
144148

145-
if not screen and self.thePlayer.health <= 0:
149+
if not screen and not self.theWorld:
150+
screen = GuiMainTitle()
151+
elif not screen and self.thePlayer.health <= 0:
146152
screen = GuiGameOver()
147153

148154
self.currentScreen = screen
@@ -397,7 +403,8 @@ def run(self):
397403
if not os.path.isdir(file):
398404
raise RuntimeError(f'The working directory could not be created: {file}')
399405

400-
self.options = GameSettings(self, file)
406+
self.mcDataDir = file
407+
self.options = GameSettings(self, self.mcDataDir)
401408
self.sndManager.loadSoundSettings(self.options)
402409

403410
self.renderEngine = RenderEngine(self.options)
@@ -422,7 +429,7 @@ def run(self):
422429
world.setLevel(8, 8, 8, bytearray(512))
423430
self.setLevel(level)
424431
elif not self.theWorld:
425-
self.generateNewLevel(1, 0, 1, 0)
432+
self.displayGuiScreen(GuiMainTitle())
426433

427434
self.effectRenderer = EffectRenderer(self.theWorld, self.renderEngine)
428435

@@ -464,7 +471,9 @@ def __releaseMouse(self):
464471
if not self.ingameFocus:
465472
return
466473

467-
self.thePlayer.movementInput.resetKeyState()
474+
if self.thePlayer:
475+
self.thePlayer.movementInput.resetKeyState()
476+
468477
self.ingameFocus = False
469478
self.set_exclusive_mouse(False)
470479
self.set_mouse_position(self.width // 2, self.height // 2)
@@ -494,7 +503,16 @@ def __clickMouse(self, editMode):
494503
return
495504
elif self.objectMouseOver.typeOfHit == 1:
496505
if editMode == 0:
497-
self.objectMouseOver.entityHit.attackEntityFrom(self.thePlayer, 4)
506+
stack = self.thePlayer.inventory.getStackInSlot(self.thePlayer.inventory.currentItem)
507+
damage = items.itemsList[stack.itemID].getItemDamage() if stack else 1
508+
if damage > 0:
509+
self.objectMouseOver.entityHit.attackEntityFrom(self.thePlayer,
510+
damage)
511+
item = self.thePlayer.inventory.getCurrentItem()
512+
if item and isinstance(self.objectMouseOver.entityHit, EntityLiving):
513+
items.itemsList[item.itemID].hitEntity(item)
514+
if item.stackSize <= 0:
515+
self.thePlayer.displayGUIInventory()
498516

499517
return
500518
elif self.objectMouseOver.typeOfHit != 0:
@@ -554,10 +572,9 @@ def __resize(self, width, height):
554572
screen.setWorldAndResolution(self, screenWidth, screenHeight)
555573

556574
def __runTick(self):
557-
if not self.isGamePaused:
558-
self.playerController.onUpdate()
559-
560575
self.ingameGUI.addChatMessage()
576+
if not self.isGamePaused and self.theWorld:
577+
self.playerController.onUpdate()
561578

562579
gl.glBindTexture(gl.GL_TEXTURE_2D, self.renderEngine.getTexture('terrain.png'))
563580
self.renderEngine.updateDynamicTextures()

mc/net/minecraft/client/RenderHelper.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@ def enableStandardItemLighting():
2323
y = 0.6
2424
z = 0.8
2525
gl.glLightModelf(gl.GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0)
26-
vec = Vec3D(-0.4, 1.0, 1.0)
26+
vec = Vec3D(0.4, 1.0, -0.2)
2727
RenderHelper.__setColorBuffer(vec.xCoord, vec.yCoord, vec.zCoord,
2828
0.0).glLightfv(gl.GL_LIGHT0, gl.GL_POSITION)
2929
RenderHelper.__setColorBuffer(y, y, y, 1.0).glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE)
3030
RenderHelper.__setColorBuffer(0.0, 0.0, 0.0, 1.0).glLightfv(gl.GL_LIGHT0, gl.GL_AMBIENT)
3131
RenderHelper.__setColorBuffer(z, z, z, 1.0).glLightfv(gl.GL_LIGHT0, gl.GL_SPECULAR)
32+
vec = Vec3D(-0.4, 1.0, 0.2)
33+
RenderHelper.__setColorBuffer(vec.xCoord, vec.yCoord, vec.zCoord,
34+
0.0).glLightfv(gl.GL_LIGHT1, gl.GL_POSITION)
35+
RenderHelper.__setColorBuffer(0.6, 0.6, 0.6, 1.0).glLightfv(gl.GL_LIGHT1, gl.GL_DIFFUSE)
36+
RenderHelper.__setColorBuffer(0.0, 0.0, 0.0, 1.0).glLightfv(gl.GL_LIGHT1, gl.GL_AMBIENT)
37+
RenderHelper.__setColorBuffer(0.8, 0.8, 0.8, 1.0).glLightfv(gl.GL_LIGHT1, gl.GL_SPECULAR)
3238
gl.glShadeModel(gl.GL_SMOOTH)
3339
RenderHelper.__setColorBuffer(x, x, x, 1.0).glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT)
3440

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ def onRespawn(self, player):
3636

3737
self._mc.theWorld.setBlockWithNotify(xx, yy, zz, blockId)
3838

39-
player.inventory.mainInventory[8] = ItemStack(items.flintSteel)
40-
4139
def sendBlockRemoved(self, x, y, z):
4240
block = self._mc.theWorld.getBlockId(x, y, z)
4341
change = super().sendBlockRemoved(x, y, z)
42+
stack = self._mc.thePlayer.inventory.getCurrentItem()
43+
if stack:
44+
items.itemsList[stack.itemID].onBlockDestroyed(stack)
45+
if stack.stackSize == 0:
46+
self._mc.thePlayer.displayGUIInventory()
4447
if change:
4548
blocks.blocksList[block].dropBlockAsItem(self._mc.theWorld, x, y, z)
4649

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ def __init__(self, screen, options):
1010
self.__parentScreen = screen
1111
self.__options = options
1212

13-
def setWorldAndResolution(self, minecraft, width, height):
14-
super().setWorldAndResolution(minecraft, width, height)
13+
def initGui(self):
1514
for i, binding in enumerate(self.__options.keyBindings):
1615
self._controlList.append(GuiSmallButton(i, self.width // 2 - 155 + i % 2 * 160,
1716
self.height // 6 + 24 * (i >> 1),
@@ -25,7 +24,7 @@ def _actionPerformed(self, button):
2524
self._controlList[i].displayString = self.__options.setKeyBindingString(i)
2625

2726
if button.id == 200:
28-
self._mc.displayGuiScreen(self.__parentScreen)
27+
self.mc.displayGuiScreen(self.__parentScreen)
2928
else:
3029
self.__buttonId = button.id
3130
button.displayString = '> ' + self.__options.setKeyBindingString(button.id) + ' <'

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

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ def __init__(self, title, text):
66
self.__title = title
77
self.__text = text
88

9-
def setWorldAndResolution(self, minecraft, width, height):
10-
super().setWorldAndResolution(minecraft, width, height)
11-
129
def drawScreen(self, xm, ym):
1310
self._drawGradientRect(0, 0, self.width, self.height, -12574688, -11530224)
1411
self.drawCenteredString(self._fontRenderer, self.__title, self.width // 2, 90, 0xFFFFFF)

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

+10-8
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,32 @@
77

88
class GuiGameOver(GuiScreen):
99

10-
def setWorldAndResolution(self, minecraft, width, height):
11-
super().setWorldAndResolution(minecraft, width, height)
10+
def initGui(self):
1211
self._controlList.clear()
1312
self._controlList.append(GuiButton(1, self.width // 2 - 100, self.height // 4 + 72,
1413
'Generate new world...'))
1514
self._controlList.append(GuiButton(2, self.width // 2 - 100, self.height // 4 + 96,
1615
'Load world..'))
17-
if not self._mc.session:
16+
if not self.mc.session:
1817
self._controlList[2].enabled = False
1918

19+
def _keyTyped(self, key, char, motion):
20+
pass
21+
2022
def _actionPerformed(self, button):
2123
if button.id == 0:
22-
self._mc.displayGuiScreen(GuiOptions(self, self._mc.options))
24+
self.mc.displayGuiScreen(GuiOptions(self, self.mc.options))
2325
elif button.id == 1:
24-
self._mc.displayGuiScreen(GuiNewLevel(self))
25-
elif button.id == 2 and self._mc.session:
26-
self._mc.displayGuiScreen(GuiLoadLevel(self))
26+
self.mc.displayGuiScreen(GuiNewLevel(self))
27+
elif button.id == 2 and self.mc.session:
28+
self.mc.displayGuiScreen(GuiLoadLevel(self))
2729

2830
def drawScreen(self, xm, ym):
2931
self._drawGradientRect(0, 0, self.width, self.height, 0x60500000, -1602211792)
3032
gl.glPushMatrix()
3133
gl.glScalef(2.0, 2.0, 2.0)
3234
self.drawCenteredString(self._fontRenderer, 'Game over!', self.width // 2 // 2, 30, 0xFFFFFF)
3335
gl.glPopMatrix()
34-
self.drawCenteredString(self._fontRenderer, 'Score: &e' + str(self._mc.thePlayer.getScore()),
36+
self.drawCenteredString(self._fontRenderer, 'Score: &e' + str(self.mc.thePlayer.getScore()),
3537
self.width // 2, 100, 0xFFFFFF)
3638
super().drawScreen(xm, ym)

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

+5-10
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,16 @@ def renderGameOverlay(self, a):
8787
gl.glTranslatef(-(width + 8), -(height + 12), 0.0)
8888

8989
self.__itemRenderer.renderItemIntoGUI(
90-
self.__mc.fontRenderer, self.__mc.renderEngine,
90+
self.__mc.renderEngine,
9191
stack, width, height
9292
)
9393
if anim > 0.0:
9494
gl.glPopMatrix()
9595

96-
if stack.stackSize > 1:
97-
size = str(stack.stackSize)
98-
gl.glDisable(gl.GL_LIGHTING)
99-
gl.glDisable(gl.GL_DEPTH_TEST)
100-
self.__mc.fontRenderer.drawStringWithShadow(
101-
size, width + 19 - 2 - self.__mc.fontRenderer.getStringWidth(size),
102-
height + 6 + 3, 16777215)
103-
gl.glEnable(gl.GL_LIGHTING)
104-
gl.glEnable(gl.GL_DEPTH_TEST)
96+
self.__itemRenderer.renderItemDamage(
97+
self.__mc.fontRenderer,
98+
stack, width, height
99+
)
105100

106101
RenderHelper.disableStandardItemLighting()
107102
gl.glDisable(gl.GL_NORMALIZE)

0 commit comments

Comments
 (0)