Skip to content

Commit a652c89

Browse files
0.0.18a_02
1 parent ba0d23a commit a652c89

22 files changed

+277
-115
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
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.0.17.tar.gz
15+
pip install dist/minecraft-python-0.0.18a2.tar.gz
1616

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

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

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

7-
This project is currently recreating the **Multiplayer Classic** versions of Minecraft. The latest version is **Classic 0.0.17a** as released on _**June 10, 2009**_.
7+
This project is currently recreating the **Multiplayer Classic** versions of Minecraft. The latest version is **Classic 0.0.18a_02** as released on _**June 14, 2009**_.
88

9-
Learn more about this version [here](https://minecraft.fandom.com/wiki/Java_Edition_Classic_0.0.17a).
9+
Learn more about this version [here](https://minecraft.fandom.com/wiki/Java_Edition_Classic_0.0.18a_02).
1010

11-
Or the server version [here](https://minecraft.fandom.com/wiki/Java_Edition_Classic_server_1.3).
11+
Or the server version [here](https://minecraft.fandom.com/wiki/Java_Edition_Classic_server_1.4.1).
1212

1313
This project is organized so that every commit is strictly the completed release of the Python version of the Java game of the same version number.
1414
This means that you can go back into this repository's commit history and see only the source code changes between versions of Minecraft,
@@ -17,9 +17,9 @@ you can play it just by specifying the Minecraft version you want to play in the
1717

1818
### General Usage
1919

20-
*Pyglet* and *Cython* are required dependencies and can easily be installed with *pip*. Use the versions specified in `requirements.txt`.
20+
*Pyglet*, *Cython*, and *Pillow* are required dependencies and can easily be installed with *pip*. Use the versions specified in `requirements.txt`.
2121

22-
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==0.0.17`.
22+
To easily install this version of *Minecraft: Python Edition*, just run `python -m pip install minecraft-python==0.0.18a_02`.
2323

2424
Alternatively, for a manual Cython build, run `python setup.py build_ext --inplace`.
2525

mc/Resources.py

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

mc/net/minecraft/Entity.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ def setPos(self, x, y=None, z=None):
7171
self.bb = AABB(x - w, y - h, z - w, x + w, y + h, z + w)
7272

7373
def _setRot(self, yRot, xRot):
74+
while self.yRotO - yRot < -180.0:
75+
self.yRotO += 360.0
76+
77+
while self.yRotO - yRot >= 180.0:
78+
self.yRotO -= 360.0
79+
7480
self.yRot = yRot
7581
self.xRot = xRot
7682

mc/net/minecraft/Minecraft.py

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@
4141

4242
GL_DEBUG = False
4343

44+
class StopGameException(Exception):
45+
pass
46+
4447
class Minecraft(window.Window):
45-
VERSION_STRING = '0.0.17a'
48+
VERSION_STRING = '0.0.18a_02'
4649
__timer = Timer(20.0)
4750
level = None
4851
__levelRenderer = None
@@ -138,7 +141,7 @@ def __checkGlError(self, string):
138141
print(errorCode)
139142
sys.exit(1)
140143

141-
def __destroy(self):
144+
def destroy(self):
142145
try:
143146
LevelIO.save(self.level, gzip.open('level.dat', 'wb'))
144147
except Exception as e:
@@ -446,7 +449,7 @@ def run(self):
446449
lastTime += 1000
447450
frames = 0
448451

449-
self.__destroy()
452+
self.destroy()
450453

451454
def grabMouse(self):
452455
if self.__mouseGrabbed:
@@ -682,7 +685,7 @@ def __render(self, a):
682685
gl.glColorMask(True, True, True, True)
683686
if i20 > 0:
684687
gl.glEnable(gl.GL_TEXTURE_2D)
685-
gl.glBindTexture(gl.GL_TEXTURE_2D, self.__levelRenderer.textures.loadTexture('terrain.png', gl.GL_NEAREST))
688+
gl.glBindTexture(gl.GL_TEXTURE_2D, self.__levelRenderer.textures.getTextureId('terrain.png'))
686689
gl.glCallLists(self.__levelRenderer.dummyBuffer.capacity(), gl.GL_INT, self.__levelRenderer.dummyBuffer)
687690
gl.glDisable(gl.GL_TEXTURE_2D)
688691

@@ -728,7 +731,7 @@ def __renderGui(self):
728731
gl.glTranslatef(-1.5, 0.5, 0.5)
729732
gl.glScalef(-1.0, -1.0, -1.0)
730733

731-
id_ = Textures.loadTexture('terrain.png', gl.GL_NEAREST)
734+
id_ = self.__textures.getTextureId('terrain.png')
732735
gl.glBindTexture(gl.GL_TEXTURE_2D, id_)
733736
gl.glEnable(gl.GL_TEXTURE_2D)
734737
t.begin()
@@ -826,45 +829,54 @@ def __getBuffer(self, a, b, c, d):
826829
return self.__lb
827830

828831
def beginLevelLoading(self, title):
829-
self.__title = title
830-
screenWidth = self.width * 240 / self.height
831-
screenHeight = self.height * 240 / self.height
832-
833-
gl.glClear(gl.GL_DEPTH_BUFFER_BIT)
834-
gl.glMatrixMode(gl.GL_PROJECTION)
835-
gl.glLoadIdentity()
836-
gl.glOrtho(0.0, screenWidth, screenHeight, 0.0, 100.0, 300.0)
837-
gl.glMatrixMode(gl.GL_MODELVIEW)
838-
gl.glLoadIdentity()
839-
gl.glTranslatef(0.0, 0.0, -200.0)
832+
if not self.running:
833+
raise StopGameException
834+
else:
835+
self.__title = title
836+
screenWidth = self.width * 240 / self.height
837+
screenHeight = self.height * 240 / self.height
838+
839+
gl.glClear(gl.GL_DEPTH_BUFFER_BIT)
840+
gl.glMatrixMode(gl.GL_PROJECTION)
841+
gl.glLoadIdentity()
842+
gl.glOrtho(0.0, screenWidth, screenHeight, 0.0, 100.0, 300.0)
843+
gl.glMatrixMode(gl.GL_MODELVIEW)
844+
gl.glLoadIdentity()
845+
gl.glTranslatef(0.0, 0.0, -200.0)
840846

841847
def levelLoadUpdate(self, status):
842-
self.__text = status
843-
self.setLoadingProgress()
848+
if not self.running:
849+
raise StopGameException
850+
else:
851+
self.__text = status
852+
self.setLoadingProgress()
844853

845854
def setLoadingProgress(self):
846-
screenWidth = self.width * 240 // self.height
847-
screenHeight = self.height * 240 // self.height
855+
if not self.running:
856+
raise StopGameException
857+
else:
858+
screenWidth = self.width * 240 // self.height
859+
screenHeight = self.height * 240 // self.height
848860

849-
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
861+
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
850862

851-
t = tesselator
852-
gl.glEnable(gl.GL_TEXTURE_2D)
853-
id_ = self.__textures.loadTexture('dirt.png', gl.GL_NEAREST)
854-
gl.glBindTexture(gl.GL_TEXTURE_2D, id_)
855-
s = 32.0
856-
t.begin()
857-
t.color(4210752)
858-
t.vertexUV(0.0, screenHeight, 0.0, 0.0, screenHeight / s)
859-
t.vertexUV(screenWidth, screenHeight, 0.0, screenWidth / s, screenHeight / s)
860-
t.vertexUV(screenWidth, 0.0, 0.0, screenWidth / s, 0.0)
861-
t.vertexUV(0.0, 0.0, 0.0, 0.0, 0.0)
862-
t.end()
863-
864-
self.font.drawShadow(self.__title, (screenWidth - self.font.width(self.__title)) // 2, screenHeight // 2 - 4 - 16, 0xFFFFFF)
865-
self.font.drawShadow(self.__text, (screenWidth - self.font.width(self.__text)) // 2, screenHeight // 2 - 4 + 8, 0xFFFFFF)
866-
clock.tick()
867-
self.flip()
863+
t = tesselator
864+
gl.glEnable(gl.GL_TEXTURE_2D)
865+
id_ = self.__textures.getTextureId('dirt.png')
866+
gl.glBindTexture(gl.GL_TEXTURE_2D, id_)
867+
s = 32.0
868+
t.begin()
869+
t.color(4210752)
870+
t.vertexUV(0.0, screenHeight, 0.0, 0.0, screenHeight / s)
871+
t.vertexUV(screenWidth, screenHeight, 0.0, screenWidth / s, screenHeight / s)
872+
t.vertexUV(screenWidth, 0.0, 0.0, screenWidth / s, 0.0)
873+
t.vertexUV(0.0, 0.0, 0.0, 0.0, 0.0)
874+
t.end()
875+
876+
self.font.drawShadow(self.__title, (screenWidth - self.font.width(self.__title)) // 2, screenHeight // 2 - 4 - 16, 0xFFFFFF)
877+
self.font.drawShadow(self.__text, (screenWidth - self.font.width(self.__text)) // 2, screenHeight // 2 - 4 + 8, 0xFFFFFF)
878+
clock.tick()
879+
self.flip()
868880

869881
def generateLevel(self, i):
870882
name = self.user.name if self.user else 'anonymous'
@@ -917,7 +929,7 @@ def addChatMessage(self, string):
917929
elif arg == '-mppass':
918930
mpPass = sys.argv[i + 1]
919931

920-
game = Minecraft(fullScreen, width=854, height=480, caption='Minecraft 0.0.17a')
932+
game = Minecraft(fullScreen, width=854, height=480, caption='Minecraft 0.0.18a_02')
921933
game.user = User(name, 0, mpPass)
922934
if server and port:
923935
game.setServer(server, int(port))

mc/net/minecraft/character/Zombie.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def tick(self):
5151

5252
def render(self, textures, a):
5353
gl.glEnable(gl.GL_TEXTURE_2D)
54-
gl.glBindTexture(gl.GL_TEXTURE_2D, textures.loadTexture('char.png', gl.GL_NEAREST))
54+
gl.glBindTexture(gl.GL_TEXTURE_2D, textures.getTextureId('char.png'))
5555

5656
gl.glPushMatrix()
5757
t = getNs() / 1000000000.0 * 10.0 * self.speed + self.timeOffs

mc/net/minecraft/comm/SocketConnection.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ def processData(self):
129129
b25 = data[4]
130130
b8 = data[5]
131131
networkPlayer = self.manager.players.get(b15)
132-
if b15 >= 0 and networkPlayer:
132+
if b15 < 0:
133+
self.manager.minecraft.player.moveTo(s17 / 32.0, s18 / 32.0, s21 / 32.0, float(b25 * 360) / 256.0, float(b8 * 360) / 256.0)
134+
elif networkPlayer:
133135
networkPlayer.teleport(s17, s18, s21, float(-b25 * 360) / 256.0, float(b8 * 360) / 256.0)
134136
elif packet == Packets.PLAYER_MOVE_AND_ROTATE:
135137
b15 = data[0]
@@ -158,9 +160,11 @@ def processData(self):
158160
networkPlayer.queue(b23, b22, b6)
159161
elif packet == Packets.PLAYER_DISCONNECT:
160162
b15 = data[0]
161-
networkPlayer = self.manager.players.pop(b15)
162-
if b15 >= 0 and networkPlayer:
163-
self.manager.minecraft.level.entities.remove(networkPlayer)
163+
if b15 in self.manager.players:
164+
networkPlayer = self.manager.players.pop(b15)
165+
if b15 >= 0 and networkPlayer:
166+
networkPlayer.clear()
167+
self.manager.minecraft.level.entities.remove(networkPlayer)
164168
elif packet == Packets.CHAT_MESSAGE:
165169
b15 = data[0]
166170
string19 = data[1].decode()

mc/net/minecraft/gui/ChatScreen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def _keyPressed(self, key, char, motion):
2626
else:
2727
if motion == window.key.MOTION_BACKSPACE and len(self.__typedMsg) > 0:
2828
self.__typedMsg = self.__typedMsg[:-1]
29-
if char and char in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.:-_\'*!"#%/()=+?[]{}<>' and len(self.__typedMsg) < 64 - (len(self._minecraft.user.name) + 2):
29+
if char and char in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.:-_\'*!\\"#%/()=+?[]{}<>@|$' and len(self.__typedMsg) < 64 - (len(self._minecraft.user.name) + 2):
3030
self.__typedMsg += char
3131

3232
def render(self, xm, ym):

mc/net/minecraft/gui/Font.py

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Font:
66

77
def __init__(self, name, textures):
88
self.__charWidths = [0] * 256
9-
self.__fontTexture = textures.loadTexture(name, gl.GL_NEAREST)
9+
self.__fontTexture = textures.getTextureId(name)
1010
texture = Resources.textures[name]
1111
w = texture[0]
1212
h = texture[1]
@@ -38,42 +38,43 @@ def drawShadow(self, string, x, y, color):
3838
self.draw(string, x, y, color)
3939

4040
def draw(self, string, x, y, color, darken=False):
41-
if darken:
42-
color = (color & 0xFCFCFC) >> 2
43-
gl.glEnable(gl.GL_TEXTURE_2D)
44-
gl.glBindTexture(gl.GL_TEXTURE_2D, self.__fontTexture)
45-
t = tesselator
46-
t.begin()
47-
t.color(color)
48-
xo = 0
49-
i = 0
50-
while i < len(string):
51-
if string[i] == '&':
52-
cc = '0123456789abcdef'.index(string[i + 1])
53-
br = (cc & 8) << 3
54-
b = (cc & 1) * 191 + br
55-
g = ((cc & 2) >> 1) * 191 + br
56-
r = ((cc & 4) >> 2) * 191 + br
57-
color = r << 16 | g << 8 | b
58-
i += 2
59-
if darken:
60-
color = (color & 0xFCFCFC) >> 2
41+
if string is not None:
42+
if darken:
43+
color = (color & 0xFCFCFC) >> 2
44+
gl.glEnable(gl.GL_TEXTURE_2D)
45+
gl.glBindTexture(gl.GL_TEXTURE_2D, self.__fontTexture)
46+
t = tesselator
47+
t.begin()
48+
t.color(color)
49+
xo = 0
50+
i = 0
51+
while i < len(string):
52+
if string[i] == '&':
53+
cc = '0123456789abcdef'.index(string[i + 1])
54+
br = (cc & 8) << 3
55+
b = (cc & 1) * 191 + br
56+
g = ((cc & 2) >> 1) * 191 + br
57+
r = ((cc & 4) >> 2) * 191 + br
58+
color = r << 16 | g << 8 | b
59+
i += 2
60+
if darken:
61+
color = (color & 0xFCFCFC) >> 2
6162

62-
t.color(color)
63+
t.color(color)
6364

64-
ix = ord(string[i]) % ord('\020') << 3
65-
iy = ord(string[i]) // ord('\020') << 3
66-
f13 = 7.99
67-
t.vertexUV(x + xo, y + f13, 0.0, ix / 128.0, (iy + f13) / 128.0)
68-
t.vertexUV(x + xo + f13, y + f13, 0.0, (ix + f13) / 128.0, (iy + f13) / 128.0)
69-
t.vertexUV(x + xo + f13, y, 0.0, (ix + f13) / 128.0, iy / 128.0)
70-
t.vertexUV(x + xo, y, 0.0, ix / 128.0, iy / 128.0)
65+
ix = ord(string[i]) % ord('\020') << 3
66+
iy = ord(string[i]) // ord('\020') << 3
67+
f13 = 7.99
68+
t.vertexUV(x + xo, y + f13, 0.0, ix / 128.0, (iy + f13) / 128.0)
69+
t.vertexUV(x + xo + f13, y + f13, 0.0, (ix + f13) / 128.0, (iy + f13) / 128.0)
70+
t.vertexUV(x + xo + f13, y, 0.0, (ix + f13) / 128.0, iy / 128.0)
71+
t.vertexUV(x + xo, y, 0.0, ix / 128.0, iy / 128.0)
7172

72-
xo += self.__charWidths[ord(string[i])]
73-
i += 1
73+
xo += self.__charWidths[ord(string[i])]
74+
i += 1
7475

75-
t.end()
76-
gl.glDisable(gl.GL_TEXTURE_2D)
76+
t.end()
77+
gl.glDisable(gl.GL_TEXTURE_2D)
7778

7879
def width(self, string):
7980
if string is None:

0 commit comments

Comments
 (0)