From 19a78eb3bfaa14367d22eab4ed83376e34ff8a04 Mon Sep 17 00:00:00 2001 From: justuswolff Date: Sat, 25 May 2024 22:21:27 +0200 Subject: [PATCH] SEQ fix --- hashengine.py | 2 +- main.py | 46 +- .../out/__pycache__/player.cpython-310.pyc | Bin 0 -> 28995 bytes testbuilds/SEQSID/out/game.HEGF | 1 + testbuilds/SEQSID/out/hashengine.py | 378 ++++++ testbuilds/SEQSID/out/main.py | 7 + testbuilds/SEQSID/out/mtTkinter.py | 230 ++++ testbuilds/SEQSID/out/player.py | 1050 +++++++++++++++++ tests/SEQTEST | 1 + 9 files changed, 1700 insertions(+), 15 deletions(-) create mode 100644 testbuilds/SEQSID/out/__pycache__/player.cpython-310.pyc create mode 100644 testbuilds/SEQSID/out/game.HEGF create mode 100644 testbuilds/SEQSID/out/hashengine.py create mode 100644 testbuilds/SEQSID/out/main.py create mode 100644 testbuilds/SEQSID/out/mtTkinter.py create mode 100644 testbuilds/SEQSID/out/player.py create mode 100644 tests/SEQTEST diff --git a/hashengine.py b/hashengine.py index 4b5f9b9..3baf0e7 100644 --- a/hashengine.py +++ b/hashengine.py @@ -206,7 +206,7 @@ class seqobj: def moveby(self, pos): for i in self._objects: - i.position + pos + i.position += pos class game: def __init__(self, size=[10, 10], renderer=stdrend, sounddir=""): diff --git a/main.py b/main.py index 6945414..f1f8940 100644 --- a/main.py +++ b/main.py @@ -475,20 +475,25 @@ def importobj(target): id["args"].update(outargs) return oid -def load(cleargame=True, GUI=True, path=""): +def load(cleargame=True, GUI=True, path="", override=False): if GUI == True: file = filedialog.askopenfile() - else: + elif override == False: file = open(path, 'r') tempwin = tk.Tk() ptext = tk.Label(tempwin, text="NONE") ptext.place(y=30) stat = tk.Label(tempwin, text="NONE") stat.place(y=50) - target = file.read() - file.close() + if override == False: + target = file.read() + file.close() + else: + target = override target = ast.literal_eval(target) if cleargame: + global models + models = [] clear() if len(target) == 0: return if not isinstance(target[0], list): @@ -520,13 +525,16 @@ def load(cleargame=True, GUI=True, path=""): if id: ids[count-1] = id count += 1 - if GUIe == True: - for i in target[1]: - tempid = genid() - objtree.insert("", tk.END, text=i, image=icons["model"], iid=tempid, tags=("HASHMODEL",)) - for f in target[1][i]: + for i in target[1]: + tempid = genid() + if GUIe == True: objtree.insert("", tk.END, text=i, image=icons["model"], iid=tempid, tags=("HASHMODEL",)) + temp = [] + for f in target[1][i]: + if GUIe == True: objtree.detach(ids[f]) objtree.move(ids[f], tempid, "end") + temp.append(ids[f]) + models.append(temp) tempwin.destroy() preview.render() @@ -617,21 +625,28 @@ def run(): i = gamedata[i] if i["id"] != "sound" and i["id"] != "rawsound": continue maingame.sounds[i["args"]["spath"]] = i["args"]["sdata"] - skip = [] + #skip = [] for i in gamedata: GID = i i = gamedata[i] if i["id"] != "obj": continue objid = i["args"]["ID"] maingame._SIDS[i["SID"]] = objid - if objtree.parent(GID) != "" and not objtree.parent(GID) in skip: + """if objtree.parent(GID) != "" and not objtree.parent(GID) in skip: skip.append(objtree.parent(GID)) out = "" out2 = [] for f in objtree.get_children(objtree.parent(GID)): out = out + gamedata[f]["SID"][:5] out2.append(f) - maingame._SEQSIDS[out] = out2 + maingame._SEQSIDS[out] = out2""" + for i in models: + out = [] + SEQSID = "" + for f in i: + SEQSID = SEQSID + gamedata[f]["SID"][:5] + out.append(gamedata[f]["args"]["ID"]) + maingame._SEQSIDS[SEQSID] = out maingame._objects = copy.deepcopy(preview._objects) """ @@ -777,6 +792,8 @@ def GUIinit(): global preview global GUIe global clog + global models + models = [] GUIe = True container = tk.Tk() container.bind("", updatepreviewcam, add="+") @@ -966,10 +983,11 @@ def execgame(gametree, shouldlog=True): global GUIe global preview global clog + global models preview = hashengine.game(renderer=nullrend, sounddir="/") GUIe = False - for i in gametree[0]: - importobj(i) + models = [] + load(False, False, "", str(gametree)) clog = shouldlog run() diff --git a/testbuilds/SEQSID/out/__pycache__/player.cpython-310.pyc b/testbuilds/SEQSID/out/__pycache__/player.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..062779edda0e7e88873d782600a977b7de2ab451 GIT binary patch literal 28995 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мY zvCHRX);xgvL(Kl(8~SG(8`_+$`Pt84J*8V#;ELHeUC-#j{c zkwM-9HNc>?BYy)^@Dr@$YnjMU8)hXgXrg-xo8=as&Ck?A&IePvybJj#Zam?BCx}c+ zI>FviYG%QvFe(49hFBLj?x~m*(ZvaonB%5>i>>)yroBx^m?be}Acir@tnKtsZ4b;X z|2TjjkP-58Zc@RZY6T&qA3@eHVoc^TUYuyyTmX`k+vc2OJdEcSg*vx?VUNTWG*e<~ z(RTLGiZF^t@h*46shhMy{l))mg>rS3*Da)x&lPK)2jE}Lo>Z)Zzr>ho*K`0k-J z+O!QGy5X++HMtg{AU=UKucLRri`s6nHXnuunlWpRU4I;@AkI3Ni4)TJ(T{2jt+Epy zZU9~+Ujo7>H^O^_G(0B9!C3gkIGKYdVQs`=zR}-`>ABB;-yr|?K$u&Z6>fzf$*U7G zWX)N^jB!O)qqStR{-7~gyta%_+mqvO&6WN-Hon@_aExC@S^f3Q!H~#fZkrp<+)+HT zwnlWJ>@k>!iTI+vwpqK9x`Z38qSY@~QiE3+po{KH-6a23?Z+V`{CAFlbKD&h;Q^N5 z^Bl8?a}q4cIzW1gc1Y}?WCLA5rrS0n>M|WBvZF8yhmlrPgj*0;kk8T~oz|>0QL&5B z>Z8n<(H}waAb~H9Tq%b0t?%
j;$`bMPdZ(=5YRO9L&KP~(`isIAerMZ!D{eHH= z9?Fi#Jp2v(5x)vw()$p65W$OC_o7jqoj}YslsJ*KE@nTVKh3;-AV$NSe0(rBJRi!X zQvAP+h82X|LITP)HW8ZhCqfZ(4VmkvpJpEf!0=?s|H?6Ehx}{g;=mOL~wQ9;S1e&R;Q?=+B;|PZsYb`re}Ry>xz% z&M+Mjru;H}B2oDr`fk$sGMzu9bC}K_)A@5cBBcRk858M>5w`G7tlVNWVwV91FER5@ z`e?Rjq$mWNVsEreo+2`qA7^GRjDfL~!HFEgY!mXQ!u$yfrezP4;SjDs$PmF50#F6A zn7#f}s4s9KYnd|J_@A);C+QFdn$H~^qwhGK19U#YS~KD>*uFJk{|UJQ{@>C;WQdi2 z9gZLKKo{|HXXD0=pTeKz;nFp~kKeG%Xn(tc1$;Ymf2J$*Wade~GnMdr{G^}oxBFeb zCw~cq`uvT4CqhX-ncC_fN_F|EjN|wFY5!T@MLT!;iOmUr(0>In8N{%RgZJjt=1e*h g_tKk%)weCL(+1nW`k(iw=^huhY~J6bTpEP^Eiix}fB*mh literal 0 HcmV?d00001 diff --git a/testbuilds/SEQSID/out/game.HEGF b/testbuilds/SEQSID/out/game.HEGF new file mode 100644 index 0000000..8be57bc --- /dev/null +++ b/testbuilds/SEQSID/out/game.HEGF @@ -0,0 +1 @@ +[[{'id': 'obj', 'name': 'Objekt', 'SID': 'cUwnltshBNeQQFvuwfXuUzsaHaJKyxSqwztnBteAIHrqzsOgEljfWOOGmzgCLgsuYxfyTyMehQXFcQWHCLmBWCMAPieboGymJOoNPKboUUtSuJUvjLLFYycsukzeHVBGcIUfZzJBJYUoFVTBhYKuLqYpwWrIWrEdUPjPpXUhKGEuolPGBHYmativzBekLKGEEKvpIWvPQoDhoAzVZaevzQAisacPettAjoEynVhDkSUggmsTjXqqutysffacbzD', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 0, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'SID': 'kzjhJQJZTwwBnsqFbMMWwoubynoPJVuFLPGlTMODHNbtIkqmYlCdwDQAgXEGrNemqizGeVajNuLScIftEjGfMgUVhFPYdXFDkKdyHJVdTascWZDJmZPmhTSiYWhnsvONfVvmHOmVeJrwHgjeHgDChAEkDXrDLbhoqVkpVvNaQgpecMqHaojBRGqlaDysXUYBSILmzOHbsllKaPxyPeGWNDTQkViUqdfPmfAYknybhPcGowVWzPaIijmbkFxYxyZ', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 1, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'SID': 'ypuYPxrQJbjLqPCIRSUjaSLKTjYRWFkldnHeHzaDuqTFcKbAVuqmKwadBqCrCyoNarxWlSCzIeeBpTIUCXNGWbMKtsmIsxUawwictmxqSRDwZyOdeqPYeMEeJaxwbpIovYpbHvbMglAfaOnQCXKqfStBXYURpfxUCrzDVnJzJMbuxWVHksdZQSjhChZTVAZrSChBrRQhkYCnsJqwxhEzrhjZgWIgaGopmAgQZnFFtQltSVovxbqvvTkquUEdswM', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 2, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'script', 'name': 'Skript', 'SID': 'nWvowGAstSdSoUbpAoSoXlogKgfAApqyiiCEcfcEOUnCvthUiozkobNUlUNbiBdrzKdajEXAkrHbwQtGMExMWpDYoXRUVecdfvGYntJnKYdviiXSdcrsoTldVBOBQUgWylLBysTmVipXvBtyjOXOtvgrOqKWcdRjRNRhXqdNBRwCBrbpfHVxJIbGIttQZFYoypouuYexsLAwDtxlJdhZhYYpyQJTpJtGmLVFNcnJWUYejTDanpUfCVJZkfbRLXC', 'args': {'code': 'import time\nobj = HASHGAME.getobjseqbySID("cUwnlkzjhJypuYP")\ntime.sleep(3)\nobj.moveby(HASHBASE.vector2(0, 3))'}}], {'Erstellte Objekte': [0, 1, 2]}] \ No newline at end of file diff --git a/testbuilds/SEQSID/out/hashengine.py b/testbuilds/SEQSID/out/hashengine.py new file mode 100644 index 0000000..3baf0e7 --- /dev/null +++ b/testbuilds/SEQSID/out/hashengine.py @@ -0,0 +1,378 @@ +import tkinter as tk +import string +import random +import threading +import time +import wave +import os + +class stdrend: + def __init__(self, size, cam): + self._size = size + self._grid = {} + self._win = tk.Tk() + + tkeys = list(string.ascii_letters) + self._keys = {} + for i in tkeys: + self._keys[i] = False + self._win.bind("", self.keypupd) + self._win.bind("", self.keydupd) + + for y in range(size[1]): + for x in range(size[0]): + temp = tk.Label(text=" ") + temp.grid(row=y, column=x) + self._win.update() + self._grid[f"{x}:{y}"] = temp + + def keypupd(self, event): + event = event.char + if event in self._keys: + self._keys[event] = True + + def keydupd(self, event): + event = event.char + if event in self._keys: + self._keys[event] = False + + def getkeys(self): + return self._keys + + def coltohex(self, target): + colors = [] + target = [target.r, target.g, target.b] + for i in target: + colors.append(("0"*(2-len(hex(i)[2:])))+hex(i)[2:]) + out = "" + for i in colors: + out = out + i + return "#"+out + + def update(self): + self._win.update() + + def pix(self, x, y, text, bcolor, fcolor): + if f"{x}:{y}" in self._grid: + self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor)) + +class color3: + def __init__(self, r=0, g=0, b=0): + self.r = r + self.g = g + self.b = b + self._type = "color3" + + def __add__(self, v): + temp = color3(self.r+v.r, self.g+v.g, self.b+v.b) + temp.r = temp.r%255 + temp.g = temp.g%255 + temp.b = temp.b%255 + return temp + + def __sub__(self, v): + temp = color3(self.r-v.r, self.g-v.g, self.b-v.b) + temp.r = temp.r%255 + temp.g = temp.g%255 + temp.b = temp.b%255 + return temp + + def __mul__(self, v): + temp = color3(self.r*v.r, self.g*v.g, self.b*v.b) + temp.r = temp.r%255 + temp.g = temp.g%255 + temp.b = temp.b%255 + return temp + + def __iadd__(self, v): + temp = color3(self.r+v.r, self.g+v.g, self.b+v.b) + temp.r = temp.r%255 + temp.g = temp.g%255 + temp.b = temp.b%255 + return temp + + def __isub__(self, v): + temp = color3(self.r-v.r, self.g-v.g, self.b-v.b) + temp.r = temp.r%255 + temp.g = temp.g%255 + temp.b = temp.b%255 + return temp + + def __imul__(self, v): + temp = color3(self.r*v.r, self.g*v.g, self.b*v.b) + temp.r = temp.r%255 + temp.g = temp.g%255 + temp.b = temp.b%255 + return temp + +class vector2: + def __init__(self, x=0, y=0): + self.x = x + self.y = y + self._type = "vector2" + + def _magnitude(self): + return abs(self.x+self.y) + + def __add__(self, v): + return vector2(self.x+v.x, self.y+v.y) + + def __sub__(self, v): + return vector2(self.x-v.x, self.y-v.y) + + def __mul__(self, v): + return vector2(self.x*v.x, self.y*v.y) + + def __iadd__(self, v): + return vector2(self.x+v.x, self.y+v.y) + + def __isub__(self, v): + return vector2(self.x-v.x, self.y-v.y) + + def __imul__(self, v): + return vector2(self.x*v.x, self.y*v.y) + +class NULL: + def __init__(self): + return None + +class enum: + def __init__(self, sel): + self._sel = dict(sel) + for i in self._sel: + setattr(self, i, self._sel[i]) + + def getposssel(self): + return list(self._sel.keys()) + +def loadsound(path): + with wave.open(path) as fd: + frames = fd.readframes(1000000000) + return frames + +cammode = enum({"editable": 0, "follow": 1}) + +class event: + def __init__(self): + self._attached = [] + + def execute(self): + threads = [] + for i in self._attached: + temp = threading.Thread(target=i) + temp.start() + threads.append(temp) + return threads + + def attach(self, target): + self._attached.append(target) + +class obj: + def __init__(self): + self.position = vector2() + self.char = " " + self.ID = 0 + self.gravity = 0 + self.acceleration = vector2() + self.velocity = vector2() + self.friction = 0 + self.collide = True + self.anchored = False + self.bcolor = color3(255, 255, 255) + self.fcolor = color3() + self._touching = event() + +class model: + def __init__(self, objects): + self._objects = objects + self.ID = 0 + +class camera(obj): + def __init__(self): + super().__init__() + self.mode = cammode.editable + self.subject = None + self.collide = False + self.touch = False + self.char = " " + + def update(self): + if self.mode == cammode.follow and self.subject: + self.position = self.subject.position + +class seqobj: + def __init__(self, objects): + self._objects = objects + + def moveby(self, pos): + for i in self._objects: + i.position += pos + +class game: + def __init__(self, size=[10, 10], renderer=stdrend, sounddir=""): + if renderer == None: raise TypeError("Renderer class needed!") + self.sounds = {} + self.currentsounds = [] + for i in os.listdir(sounddir): + if not "." in i: continue + if i.split(".")[1] != "wav": continue + self.sounds[i.split(".")[0]] = loadsound(sounddir+"/"+i) + self._size = size + self._objects = {} + self._SIDS = {} + self._SEQSIDS = {} + self.camera = camera() + self._renderer = renderer(size, self.camera) + self._threads = [] + + def getobjbySID(self, target): + return self._objects[self._SIDS[target]] + + def getobjseqbySID(self, target): + out = [] + for i in self._SEQSIDS[target]: + out.append(self._objects[i]) + return seqobj(out) + + def isdown(self, key): + temp = self._renderer.getkeys() + if key in temp: + return temp[key] + + def collidingpos(self, pos, ignore): + out = [] + for i in self._objects: + i = self._objects[i] + if i in ignore: continue + if (i.position-pos)._magnitude() < 1 and i.collide == True: + out.append(i) + return out + + def colliding(self, target): + out = [] + if target.collide == False: return [] + out = self.collidingpos(target.position, [target,]) + return out + + def handlecollision(self, target: obj, target2: obj): + if target2.anchored == True: + target.velocity = vector2() + else: + half = vector2(target.velocity.x/2, target.velocity.y/2) + target.velocity = vector2(half.x, half.y) + target2.velocity = half + self._threads.extend(target._touching.execute()) + self._threads.extend(target2._touching.execute()) + + def calcphysobj(self, target: obj): + opos = vector2(target.position.x, target.position.y) + collide = False + if target.anchored == True: return [opos, collide] + if target.collide == True: + colliding = self.collidingpos(target.position+target.velocity, [target,]) + for i in colliding: + target._touching.execute() + i._touching.execute() + self.handlecollision(target, i) + collide = True + target.position += target.velocity + target.velocity += vector2(0, target.gravity) + target.velocity += target.acceleration + temp = 2 + if target.friction != 0: + temp = 2 / target.friction + x = target.velocity.x + y = target.velocity.y + if x != 0: + x = x/temp + if y != 0: + y = y/temp + target.velocity = vector2(x, y) + return [opos, collide] + + def calcphysmodel(self, target: model): + for i in target._objects: + self.calcphysobj(i) + + def addobj(self, obj): + id = "" + for i in range(256): + id = id + random.choice(list(string.ascii_letters)) + obj.ID = id + self._objects[id] = obj + + def removeobj(self, obj): + self._objects.pop(obj.ID) + obj.ID = NULL() + + def removeobjbyid(self, id): + self._objects.pop(id).ID = NULL() + + def between(self, min, max, target): + if min < target < max: return True + return False + + def getobjbyid(self, id): + return self._objects[id] + + def render(self): + tochange = [] + for x in range(self._size[0]): + for y in range(self._size[1]): + tochange.append((x, y)) + #self._renderer.pix(x, y, " ", color3(255, 255, 255), color3(255, 255, 255)) + for i in list(self._objects.values()): + if isinstance(i, obj): + pos = i.position + self.camera.position + if not self.between(-1, self._size[0], pos.x) or not self.between(-1, self._size[1], pos.y): continue# + pos = vector2(round(pos.x), round(pos.y)) + self._renderer.pix(pos.x, pos.y, i.char, i.bcolor, i.fcolor) + if (pos.x, pos.y) in tochange: tochange.remove((pos.x, pos.y)) + if isinstance(i, model): + for tobj in i._objects: + pos = tobj.position + self.camera.position + if not self.between(-1, self._size[0], pos.x) or not self.between(-1, self._size[1], pos.y): continue# + pos = vector2(round(pos.x), round(pos.y)) + self._renderer.pix(pos.x, pos.y, tobj.char, tobj.bcolor, tobj.fcolor) + if (pos.x, pos.y) in tochange: tochange.remove((pos.x, pos.y)) + for i in tochange: + self._renderer.pix(i[0], i[1], " ", color3(255, 255, 255), color3(255, 255, 255)) + self._renderer.update() + + def startscript(self, target): + temp = threading.Thread(target=target) + temp.start() + self._threads.append(temp) + + def stopscripts(self): + for i in self._threads: + i.join(.0) + + def stopsounds(self): + for i in self.currentsounds: + i.stop() + +if __name__ == "__main__": + testgame = game(sounddir="testsound") + object = obj() + object.char = "#" + object.anchored = False + object.position = vector2(5, 5) + object.gravity = 1 + floor = obj() + floor.char = "#" + floor.anchored = True + floor.position = vector2(5, 9) + floor.gravity = 0 + floor.bcolor = color3(255, 255, 255) + testgame.addobj(object) + testgame.addobj(floor) + testgame.render() + print(object.ID) + while True: + testgame.calcphysobj(object) + testgame.calcphysobj(floor) + testgame.render() + time.sleep(0) + + diff --git a/testbuilds/SEQSID/out/main.py b/testbuilds/SEQSID/out/main.py new file mode 100644 index 0000000..d9ea702 --- /dev/null +++ b/testbuilds/SEQSID/out/main.py @@ -0,0 +1,7 @@ + +import player +import ast +file = open("game.HEGF", 'r') +file = file.read() +file = ast.literal_eval(file) +player.execgame(file) diff --git a/testbuilds/SEQSID/out/mtTkinter.py b/testbuilds/SEQSID/out/mtTkinter.py new file mode 100644 index 0000000..87bedc7 --- /dev/null +++ b/testbuilds/SEQSID/out/mtTkinter.py @@ -0,0 +1,230 @@ +'''Thread-safe version of tkinter. + +Copyright (c) 2014, Andrew Barnert + +Based on mtTkinter (for Python 2.x), copyright (c) 2009, Allen B. Taylor + +This module is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 Public License for more details. + +You should have received a copy of the GNU Lesser Public License +along with this program. If not, see . + +Usage: + + import mttkinter as tkinter + # Use "t." as usual. + +or + + from mtt import * + # Use tkinter module definitions as usual. + +This module modifies the original tkinter module in memory, making all +functionality thread-safe. It does this by wrapping the Tk class' tk +instance with an object that diverts calls through an event queue when +the call is issued from a thread other than the thread in which the Tk +instance was created. The events are processed in the creation thread +via an 'after' event. + +The modified Tk class accepts two additional keyword parameters on its +__init__ method: + mtDebug: + 0 = No debug output (default) + 1 = Minimal debug output + ... + 9 = Full debug output + mtCheckPeriod: + Amount of time in milliseconds (default 100) between checks for + out-of-thread events when things are otherwise idle. Decreasing + this value can improve GUI responsiveness, but at the expense of + consuming more CPU cycles. + +Note that, because it modifies the original tkinter module (in memory), +other modules that use tkinter (e.g., Pmw) reap the benefits automagically +as long as mttkinter is imported at some point before extra threads are +created. + +Author: Allen B. Taylor, a.b.taylor@gmail.com +''' +import sys +import threading +if sys.version_info[0] == 2: + # Python 2 + from Tkinter import * + import Queue as queue +else: + # Python 3 + from tkinter import * + import queue + + +class _Tk(object): + """Wrapper for underlying attribute tk of class Tk""" + + def __init__(self, tk, mt_debug=0, mt_check_period=10): + """ + :param tk: Tkinter.Tk.tk Tk interpreter object + :param mt_debug: Determines amount of debug output. + 0 = No debug output (default) + 1 = Minimal debug output + ... + 9 = Full debug output + :param mt_check_period: Amount of time in milliseconds (default + 10) between checks for out-of-thread events when things are + otherwise idle. Decreasing this value can improve GUI + responsiveness, but at the expense of consuming more CPU + cycles. + + # TODO: Replace custom logging functionality with standard + # TODO: logging.Logger for easier access and standardization + """ + self._tk = tk + + # Create the incoming event queue + self._event_queue = queue.Queue(1) + + # Identify the thread from which this object is being created + # so we can tell later whether an event is coming from another + # thread. + self._creation_thread = threading.current_thread() + + # Create attributes for kwargs + self._debug = mt_debug + self._check_period = mt_check_period + # Destroying flag to be set by the .destroy() hook + self._destroying = False + + def __getattr__(self, name): + """ + Diverts attribute accesses to a wrapper around the underlying tk + object. + """ + return _TkAttr(self, getattr(self._tk, name)) + + +class _TkAttr(object): + """Thread-safe callable attribute wrapper""" + + def __init__(self, tk, attr): + self._tk = tk + self._attr = attr + + def __call__(self, *args, **kwargs): + """ + Thread-safe method invocation. Diverts out-of-thread calls + through the event queue. Forwards all other method calls to the + underlying tk object directly. + """ + + # Check if we're in the creation thread + if threading.current_thread() == self._tk._creation_thread: + # We're in the creation thread; just call the event directly + if self._tk._debug >= 8 or \ + self._tk._debug >= 3 and self._attr.__name__ == 'call' and \ + len(args) >= 1 and args[0] == 'after': + print('Calling event directly:', self._attr.__name__, args, kwargs) + return self._attr(*args, **kwargs) + else: + if not self._tk._destroying: + # We're in a different thread than the creation thread; + # enqueue the event, and then wait for the response. + response_queue = queue.Queue(1) + if self._tk._debug >= 1: + print('Marshalling event:', self._attr.__name__, args, kwargs) + self._tk._event_queue.put((self._attr, args, kwargs, response_queue), True, 1) + is_exception, response = response_queue.get(True, None) + + # Handle the response, whether it's a normal return value or + # an exception. + if is_exception: + ex_type, ex_value, ex_tb = response + raise ex_type(ex_value, ex_tb) + return response + + +def _Tk__init__(self, *args, **kwargs): + """ + Hook for Tkinter.Tk.__init__ method + :param self: Tk instance + :param args, kwargs: Arguments for Tk initializer + """ + # We support some new keyword arguments that the original __init__ method + # doesn't expect, so separate those out before doing anything else. + new_kwnames = ('mt_check_period', 'mt_debug') + new_kwargs = { + kw_name: kwargs.pop(kw_name) for kw_name in new_kwnames + if kwargs.get(kw_name, None) is not None + } + + # Call the original __init__ method, creating the internal tk member. + self.__original__init__mtTkinter(*args, **kwargs) + + # Replace the internal tk member with a wrapper that handles calls from + # other threads. + self.tk = _Tk(self.tk, **new_kwargs) + + # Set up the first event to check for out-of-thread events. + self.after_idle(_check_events, self) + + +# Define a hook for class Tk's destroy method. +def _Tk_destroy(self): + self.tk._destroying = True + self.__original__destroy() + + +def _check_events(tk): + """Checks events in the queue on a given Tk instance""" + + used = False + try: + # Process all enqueued events, then exit. + while True: + try: + # Get an event request from the queue. + method, args, kwargs, response_queue = tk.tk._event_queue.get_nowait() + except queue.Empty: + # No more events to process. + break + else: + # Call the event with the given arguments, and then return + # the result back to the caller via the response queue. + used = True + if tk.tk._debug >= 2: + print('Calling event from main thread:', method.__name__, args, kwargs) + try: + response_queue.put((False, method(*args, **kwargs))) + except SystemExit: + raise # Raises original SystemExit + except Exception: + # Calling the event caused an exception; return the + # exception back to the caller so that it can be raised + # in the caller's thread. + from sys import exc_info # Python 2 requirement + ex_type, ex_value, ex_tb = exc_info() + response_queue.put((True, (ex_type, ex_value, ex_tb))) + finally: + # Schedule to check again. If we just processed an event, check + # immediately; if we didn't, check later. + if used: + tk.after_idle(_check_events, tk) + else: + tk.after(tk.tk._check_period, _check_events, tk) + + +"""Perform in-memory modification of Tkinter module""" +# Replace Tk's original __init__ with the hook. +Tk.__original__init__mtTkinter = Tk.__init__ +Tk.__init__ = _Tk__init__ + +# Replace Tk's original destroy with the hook. +Tk.__original__destroy = Tk.destroy +Tk.destroy = _Tk_destroy diff --git a/testbuilds/SEQSID/out/player.py b/testbuilds/SEQSID/out/player.py new file mode 100644 index 0000000..f1f8940 --- /dev/null +++ b/testbuilds/SEQSID/out/player.py @@ -0,0 +1,1050 @@ +import sys +# Justus Jan Nico Wolff +sys.dont_write_bytecode = True +import mtTkinter as tk +from tkinter import ttk as tkk +from tkinter import messagebox +from tkinter import filedialog +import copy +import hashengine +def norms(): + global LH + import PCPL + import langsys + PCPL.interpreter.ENG = hashengine + LH = langsys.langhandler() + lang = open("clang", 'r') + lang = lang.read() + LH.setlang(lang) + # LH.string("") +def replacelh(): + global LH + class rLH: + def __init__(self): + pass + def string(self, target): + return target + def getlangs(self): + return () + LH = rLH() +if __name__ == "__main__": + norms() +else: + replacelh() +if len(sys.argv) == 2: + if sys.argv[1] == "NOLANG": + replacelh() +import ast +import subprocess +import time +import shutil +import os +import random +import string +import easygui +import base64 +import simpleaudio as sa +import multiprocessing + +global gamedata +global cooldown +global version +version = "HE2.2-Hashengine V2.2" +cooldown = False +gamedata = {} + +def prepspecified(target): + out = [] + tempwin = tk.Tk() + bar = tkk.Progressbar(tempwin) + bar.place(width=200) + ptext = tk.Label(tempwin, text="NONE") + ptext.place() + count = 1 + modellist = {} + for i in target: + id = i + i = gamedata[i] + ptext.config(text=i["name"]) + bar.step(count/len(gamedata)) + count += 1 + tempwin.update() + temp = {"id": i["id"], "name": i["name"], "SID": i["SID"],} + tempargs = {} + tosearch = {} + for arg in i["args"]: + if not arg in extypes and not arg in ignoreat and arg != "sdata": + tosearch[arg] = i["args"][arg] + continue + if arg in ignoreat and arg != "sdata": continue + if arg != "sdata": + tempargs[arg] = i["args"][arg] + else: + tempargs[arg] = str(base64.b64encode(i["args"][arg]), "ascii", "ignore") + for argname in tosearch: + arg = tosearch[argname] + temp2 = getattributes(arg) + temp2.update({"ARGID": arg._type}) + tempargs[argname] = temp2 + if objtree.parent(id) != "": + modelname = objtree.item(objtree.parent(id), "text") + if not modelname in list(modellist.keys()): + modellist[modelname] = [] + modellist[modelname].append(count-2) + temp["args"] = tempargs + out.append(temp) + tempwin.destroy() + return [out, modellist] + +class script: + def __init__(self): + self.code = "" + + def execute(self, API, log): + #old code for PCPL code execution, replaced with python code execution + """ + PCPL.resetvar() + PCPL.LIS("HASHBASE") + PCPL.run(self.code)""" + try: + exec(self.code, API) + except Exception as e: + log(f"[GAME] Exception occured in script: {e}") + +class previewrend: + def __init__(self, size, cam, container, offset): + self._size = size + self._grid = {} + self._win = container + self._frame = tk.Frame(container) + self._posframe = tk.Frame(self._frame) + self._cam = cam + self._xcam = tk.Label(self._posframe, text="-") + self._ycam = tk.Label(self._posframe, text="-") + self._xcam.grid(row=size[1], column=0) + self._ycam.grid(row=size[1]+1, column=0) + + tkeys = list(string.ascii_letters) + self._keys = {} + for i in tkeys: + self._keys[i] = False + self._win.bind("", self.keypupd, add="+") + self._win.bind("", self.keydupd, add="+") + + for y in range(size[1]): + for x in range(size[0]): + temp = tk.Label(self._frame, text=" ", borderwidth=1, relief=tk.GROOVE, width=3) + temp.grid(row=y+offset[1], column=x+offset[0]+1) + self._win.update() + self._grid[f"{x}:{y}"] = temp + self._posframe.grid() + self._frame.grid() + + def keypupd(self, event): + event = event.char + if event in self._keys: + self._keys[event] = True + + def keydupd(self, event): + event = event.char + if event in self._keys: + self._keys[event] = False + + def getkeys(self): + return self._keys + + def coltohex(self, target): + colors = [] + target = [target.r, target.g, target.b] + for i in target: + colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:]) + out = "" + for i in colors: + out = out + i + return "#"+out + + def update(self): + self._win.update() + + def pix(self, x, y, text, bcolor, fcolor): + self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x)) + self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y)) + if f"{x}:{y}" in self._grid: + self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor)) + +class render: + def __init__(self, size, cam, container, offset): + self._size = size + self._grid = {} + self._win = container + self._frame = tk.Frame(container) + self._posframe = tk.Frame(self._frame) + self._cam = cam + self._xcam = tk.Label(self._posframe, text="-") + self._ycam = tk.Label(self._posframe, text="-") + #self._xcam.grid(row=size[1], column=0) + #self._ycam.grid(row=size[1]+1, column=0) + + tkeys = list(string.ascii_letters) + self._keys = {} + for i in tkeys: + self._keys[i] = False + self._win.bind("", self.keypupd) + self._win.bind("", self.keydupd) + + for y in range(size[1]): + for x in range(size[0]): + temp = tk.Label(self._frame, text=" ", width=3) + temp.grid(row=y+offset[1], column=x+offset[0]+1) + self._win.update() + self._grid[f"{x}:{y}"] = temp + self._posframe.grid() + self._frame.grid() + + def keypupd(self, event): + event = event.char + if event in self._keys: + self._keys[event] = True + + def keydupd(self, event): + event = event.char + if event in self._keys: + self._keys[event] = False + + def getkeys(self): + return self._keys + + def coltohex(self, target): + colors = [] + target = [target.r, target.g, target.b] + for i in target: + colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:]) + out = "" + for i in colors: + out = out + i + return "#"+out + + def update(self): + self._win.update() + + def pix(self, x, y, text, bcolor, fcolor): + self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x)) + self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y)) + if f"{x}:{y}" in self._grid: + self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor)) + +class nullrend: + def __init__(self, size, cam): + pass + + def getkeys(self): + pass + + def update(self): + pass + + def pix(self, x, y, text, bcolor, fcolor): + pass + +def selectlang(new): + lang = open("clang", 'w') + lang.write(new) + lang.close() + container.quit() + subprocess.Popen([sys.executable, __file__]) + +def add(objtype, parent="", render=True): + global objtree + obj = getattr(types, objtype)() + args = {} + for i in dir(obj): + if i.startswith("_"): continue + args[i] = getattr(obj, i) + temp = {"id": objtype, "args": args, "name": LH.string(objtype), "SID": genid()} + id = genid() + if GUIe == True: objtree.insert(parent, tk.END, text=LH.string(objtype), image=icons[objtype], iid=id, tags=("objsel")) + gamedata[id] = temp + if objtype in crucial: + preview.addobj(obj) + gamedata[id]["args"]["ID"] = obj.ID + if GUIe == True and render == True: preview.render() + return id + +def renameobj(): + target = objtree.focus() + if target == "": return + new = easygui.enterbox(LH.string("NN"), LH.string("rename")) + if new: + objtree.item(target, text=new) + if not "HASHMODEL" in objtree.item(target, "tags"): + gamedata[target]["name"] = new + +def delobjg(target): + objtree.delete(target) + temp = gamedata.pop(target) + if temp["id"] in crucial: + preview.removeobjbyid(temp["args"]["ID"]) + #preview.render() + +def delobj(): + target = objtree.selection() + if target == (): return + atritree.delete(*atritree.get_children()) + for i in target: + if "HASHMODEL" in objtree.item(i, "tags"): + tempwin = tk.Tk() + stat = tk.Label(tempwin, text="NONE") + stat.grid() + speed = tk.Label(tempwin, text="NONE") + speed.grid() + tempwin.update() + count = 0 + length = len(objtree.get_children(i)) + fpscount = 0 + timestamp = time.time() + fps = 0 + for f in objtree.get_children(i): + delobjg(f) + stat.config(text=f"{count}/{length}") + speed.config(text=f"{fps}/s") + tempwin.update() + count += 1 + fpscount += 1 + if time.time()-timestamp > 0.1: + fps = fpscount*10 + fpscount = 0 + timestamp = time.time() + objtree.delete(i) + tempwin.destroy() + else: + delobjg(i) + preview.render() + +def HMPC(event): + currentat = objtree.focus() + target = atritree.focus() + name = atritree.item(target, "text") + back = 0 + if name == "x": + back = aposx(0) + elif name == "y": + back = aposy(0) + for i in objtree.get_children(currentat): + if not "ID" in gamedata[i]["args"]: continue + setattr(gamedata[i]["args"]["position"], name, getattr(gamedata[i]["args"]["position"], name)+back) + setattr(preview.getobjbyid(gamedata[i]["args"]["ID"]).position, name, getattr(preview.getobjbyid(gamedata[i]["args"]["ID"]).position, name)+back) + preview.render() + +def changemodelpos(event): + atritree.delete(*atritree.get_children()) + atritree.insert("", index=tk.END, text="x", tags=("OA",)) + atritree.insert("", index=tk.END, text="y", tags=("OA",)) + atritree.insert("", index=tk.END, text="SEQSID", values=(calcseqsid(objtree.focus())), tags=("SID",)) + +def calcseqsid(target): + out = "" + for f in objtree.get_children(target): + out = out + gamedata[f]["SID"][:5] + return out + +def rpopup(event): + try: + rmenu.tk_popup(event.x_root, event.y_root) + finally: + rmenu.grab_release() + +def getattributes(target): + out = {} + for i in dir(target): + if i.startswith("_"): continue + out[i] = getattr(target, i) + return out + +def copySID(event): + target = atritree.focus() + text = atritree.item(target, "values")[0] + container.clipboard_clear() + container.clipboard_append(text) + messagebox.showinfo(LH.string("done"), LH.string("copied")) + +def updatribute(event): + global currentat + target = objtree.focus() + currentat = target + atritree.delete(*atritree.get_children()) + for i in gamedata[target]["args"]: + if i in ignoreat: continue + if i in valtypes and not i in DCTE: + val = gamedata[target]["args"][i] + atritree.insert("", tk.END, text=i, values=(val), tags=("FA", )) + elif i in valtypes and i in DCTE: + atritree.insert("", tk.END, text=i, values=(""), tags=("FA", )) + else: + root = atritree.insert("", tk.END, text=i, tags=("FA", )) + temp = getattributes(gamedata[target]["args"][i]) + for f in temp: + atritree.insert(root, tk.END, text=f, values=(temp[f]), tags=("FA", )) + atritree.insert("", tk.END, text="SID", values=(gamedata[target]["SID"]), tags=("SID", )) + +def halatribute(event): + target = atritree.focus() + name = atritree.item(target, "text") + parent = atritree.parent(target) + if name in valtypes: + if parent == "": + new = valtypes[name](gamedata[currentat]["args"][name]) + gamedata[currentat]["args"][name] = new + if "ID" in gamedata[currentat]["args"]: + temp = preview.getobjbyid(gamedata[currentat]["args"]["ID"]) + setattr(temp, name, new) + if not name in DCTE: atritree.item(target, values=(new)) + if name in DCTE: atritree.item(target, values=("")) + else: + parent = atritree.item(parent, "text") + new = valtypes[name](getattr(gamedata[currentat]["args"][parent], name)) + setattr(gamedata[currentat]["args"][parent], name, new) + if "ID" in gamedata[currentat]["args"]: + temp = preview.getobjbyid(gamedata[currentat]["args"]["ID"]) + setattr(temp, name, new) + if not name in DCTE: atritree.item(target, values=(new)) + if name in DCTE: atritree.item(target, values=("")) + preview.render() + +def updatepreviewcam(char): + global cooldown + if cooldown == True: return + cooldown = True + char = char.char + if char == "w": preview.camera.position += hashengine.vector2(y=1) + if char == "a": preview.camera.position += hashengine.vector2(x=1) + if char == "s": preview.camera.position -= hashengine.vector2(y=1) + if char == "d": preview.camera.position -= hashengine.vector2(x=1) + preview.render() + time.sleep(.0) + cooldown = False + +def save(): + target = filedialog.asksaveasfile() + target.write(str(prepspecified(gamedata))) + target.close() + messagebox.showinfo(LH.string("suc"), LH.string("save-suc")) + +def clear(): + global gamedata + objtree.delete(*objtree.get_children()) + atritree.delete(*atritree.get_children()) + gamedata = {} + preview._objects = {} + preview.camera.position = hashengine.vector2() + preview.render() + +def importsound(target): + oid = add("rawsound") + gamedata[oid]["name"] = target["name"] + gamedata[oid]["args"]["sdata"] = base64.b64decode(target["args"]["sdata"]) + gamedata[oid]["args"]["spath"] = target["args"]["spath"] + if "SID" in target: + gamedata[oid]["SID"] = target["SID"] + if GUIe == True: objtree.item(oid, text=target["name"]) + +def importobj(target): + if target["id"] == "sound" or target["id"] == "rawsound": + importsound(target) + return + oid = add(target["id"]) + id = gamedata[oid] + id["name"] = target["name"] + if "SID" in target: + id["SID"] = target["SID"] + if GUIe == True: objtree.item(oid, text=target["name"]) + #create arguments + outargs = {} + for argname in target["args"]: + arg = target["args"][argname] + if isinstance(arg, dict): + ID = arg.pop("ARGID") + obj = attypes[ID]() + for i in arg: + setattr(obj, i, arg[i]) + arg = obj + outargs[argname] = arg + #apply arguments to obj + if target["id"] in crucial: + for i in outargs: + setattr(preview.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i]) + id["args"].update(outargs) + return oid + +def load(cleargame=True, GUI=True, path="", override=False): + if GUI == True: + file = filedialog.askopenfile() + elif override == False: + file = open(path, 'r') + tempwin = tk.Tk() + ptext = tk.Label(tempwin, text="NONE") + ptext.place(y=30) + stat = tk.Label(tempwin, text="NONE") + stat.place(y=50) + if override == False: + target = file.read() + file.close() + else: + target = override + target = ast.literal_eval(target) + if cleargame: + global models + models = [] + clear() + if len(target) == 0: return + if not isinstance(target[0], list): + #old save file + count = 1 + bar = tkk.Progressbar(tempwin, maximum=len(target)) + bar.place(width=200) + for i in target: + ptext.config(text="Current: "+i["name"]) + bar.step() + stat.config(text=f"Object {count}/{len(target)}") + tempwin.update() + importobj(i) + count += 1 + tempwin.destroy() + preview.render() + else: + #new save file + count = 1 + bar = tkk.Progressbar(tempwin, maximum=len(target)) + bar.place(width=200) + ids = {} + for i in target[0]: + ptext.config(text="Current: "+i["name"]) + bar.step() + stat.config(text=f"Object {count}/{len(target)}") + tempwin.update() + id = importobj(i) + if id: + ids[count-1] = id + count += 1 + for i in target[1]: + tempid = genid() + if GUIe == True: objtree.insert("", tk.END, text=i, image=icons["model"], iid=tempid, tags=("HASHMODEL",)) + temp = [] + for f in target[1][i]: + if GUIe == True: + objtree.detach(ids[f]) + objtree.move(ids[f], tempid, "end") + temp.append(ids[f]) + models.append(temp) + tempwin.destroy() + preview.render() + +def export(): + temp = objtree.selection() + if temp == (): return + target = [] + for i in temp: + if "HASHMODEL" in objtree.item(i, "tags"): + target.extend(objtree.get_children(i)) + else: target.append(i) + back = prepspecified(target) + targetpath = filedialog.asksaveasfile() + if not targetpath: return + targetpath.write(str(back)) + targetpath.close() + messagebox.showinfo(LH.string("suc"), LH.string("save-suc")) + +def log(text, end="\n", flush=False): + global logfile + global clog + if clog: + if not os.path.exists("logs"): + os.mkdir("logs") + file = open("logs/"+logfile+".txt", 'a') + file.write(str(text)+end) + file.close() + +def NULL(): + pass + +class gsound: + def __init__(self, data, game): + self._playing = False + self._data = data + game.currentsounds.append(self) + + def play(self): + if self._playing == True: return + self._sound = sa.play_buffer(self._data, 2, 2, 44100) + self._playing = True + + def stop(self): + if self._playing == False: return + self._sound.stop() + self._playing = False + + def wait(self): + if self._playing == False: return + self._sound.wait_done() + +def testing(): + global testproc + global running + global clog + try: + if running == True: return + except: + pass + running = True + testproc = multiprocessing.Process(target=execgame, args=(prepspecified(gamedata), clog.get())) + testproc.start() + +def run(): + print("preparing log file...") + global logfile + global maingame + global window + temp = time.gmtime(time.time()) + logfile = "" + for i in temp: + logfile = logfile + "S" + str(i) + print("done") + log("Log file start!") + log(f"date: year: {temp[0]} month: {temp[1]} day: {temp[2]} hour: {temp[3]} min.: {temp[4]}, sec.: {temp[5]}") + log(f"Version: {version}") + log("Preparing API...") + API = {"print": log, "HASHBASE": hashengine} + log("Done!") + window = tk.Tk() + window.protocol("WM_DELETE_WINDOW", NULL) + maingame = hashengine.game(renderer=lambda size, cam: render(size, cam, window, [0, 0]), sounddir="/") + API["HASHGAME"] = maingame + API["SOUND"] = lambda data: gsound(data, maingame) + log("main game initalised!") + log("copying sounds...") + for i in gamedata: + i = gamedata[i] + if i["id"] != "sound" and i["id"] != "rawsound": continue + maingame.sounds[i["args"]["spath"]] = i["args"]["sdata"] + #skip = [] + for i in gamedata: + GID = i + i = gamedata[i] + if i["id"] != "obj": continue + objid = i["args"]["ID"] + maingame._SIDS[i["SID"]] = objid + """if objtree.parent(GID) != "" and not objtree.parent(GID) in skip: + skip.append(objtree.parent(GID)) + out = "" + out2 = [] + for f in objtree.get_children(objtree.parent(GID)): + out = out + gamedata[f]["SID"][:5] + out2.append(f) + maingame._SEQSIDS[out] = out2""" + for i in models: + out = [] + SEQSID = "" + for f in i: + SEQSID = SEQSID + gamedata[f]["SID"][:5] + out.append(gamedata[f]["args"]["ID"]) + maingame._SEQSIDS[SEQSID] = out + + maingame._objects = copy.deepcopy(preview._objects) + """ + objects = copy.deepcopy(preview._objects) + maingame._objects = objects""" + scripts = [] + for i in gamedata: + i = gamedata[i] + if i["id"] != "script": continue + i = i["args"]["code"] + obj = script() + obj.code = i + scripts.append(obj) + log("objects transferred!") + gamescript = """ +global HASHGAME +import time +while True: + for i in HASHGAME._objects: + i = HASHGAME._objects[i] + HASHGAME.calcphysobj(i) + HASHGAME.render() +""" + gameloopsc = script() + gameloopsc.code = gamescript + maingame.startscript(lambda: gameloopsc.execute(API, log)) + log("game test started!!!") + log("---------------------") + for i in scripts: + maingame.startscript(lambda: i.execute(API, log)) + window.mainloop() + +def muladd(target): + for i in range(10): + add(target) + +def stoptest(): + global testproc + global running + try: + if running == False: return + except: + return + testproc.terminate() + running = False + +def build(): + print("asking user for output directory...") + target = filedialog.askdirectory() + os.mkdir(target+"/out") + target = target+"/out" + print("building started") + print("generating HEGF file...") + hegf = str(prepspecified(gamedata)) + file = open(target+"/game.HEGF", 'w') + file.write(hegf) + file.close() + print("done.") + print("copying files...") + tocopy = ["mtTkinter.py", "hashengine.py"] + for i in tocopy: + print(f"copying {i}...") + shutil.copyfile(i, target+"/"+i) + shutil.copyfile(__file__, target+"/"+"player.py") + file = open(target+"/main.py", 'w') + file.write(""" +import player +import ast +file = open("game.HEGF", 'r') +file = file.read() +file = ast.literal_eval(file) +player.execgame(file) +""") + print("done.") + print("building finished!") + +def importPS(): + target = filedialog.askopenfile() + if target: + temp = add("script") + gamedata[temp]["args"]["code"] = str(target.read()) + target.close() + +def genid(): + id = "" + chars = list(string.ascii_letters) + for i in range(255): + id = id + random.choice(chars) + return id + +def COBS(target: str, offset=hashengine.vector2(), ignore=[" ",]): + origin = target + target = target.split("\n") + tempid = genid() + tempwin = tk.Tk() + stat = tk.Label(tempwin, text="NONE") + stat.grid() + speed = tk.Label(tempwin, text="NONE") + speed.grid() + tempwin.update() + if GUIe == True: objtree.insert("", tk.END, text=LH.string("IOM"), image=icons["model"], iid=tempid, tags=("HASHMODEL",)) + count = 1 + fpscount = 0 + timestamp = time.time() + fps = 0 + for i in range(len(target)): + y = i + i = target[i] + for f in range(len(i)): + x = f + f = i[x] + stat.config(text=f"{count}/{len(origin)}") + speed.config(text=f"{fps}/s") + tempwin.update() + count += 1 + fpscount += 1 + if time.time()-timestamp > 0.1: + fps = fpscount*10 + fpscount = 0 + timestamp = time.time() + if f in ignore: + continue + temp = add("obj", tempid, False) + #gamedata[temp]["args"]["ID"] + gamedata[temp]["args"]["char"] = f + setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "char", f) + gamedata[temp]["args"]["position"] = hashengine.vector2(x, y)+offset + setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "position", hashengine.vector2(x, y)+offset) + gamedata[temp]["args"]["anchored"] = True + setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "anchored", True) + gamedata[temp]["args"]["collide"] = True + setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "collide", True) + #preview.render() + preview.render() + tempwin.destroy() + +def GUIinit(): + global container + global objtree + global rmenu + global atritree + global currentat + global preview + global GUIe + global clog + global models + models = [] + GUIe = True + container = tk.Tk() + container.bind("", updatepreviewcam, add="+") + + global icons + icons = {} + + for i in os.listdir("icons"): + icons[i.split(".")[0]] = tk.PhotoImage(file=f"icons/{i}") + + #preview init + preview = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, container=container, offset=[0, 0]), sounddir="/") + + #tree init + objtree = tkk.Treeview(container, columns=("-")) + objtree.heading("#0", text=LH.string("objs")) + objtree.tag_bind("objsel", "<>", updatribute) + objtree.tag_bind("HASHMODEL", "<>", changemodelpos) + objtree.grid(row=1, column=0) + + #attribute tree init + currentat = "temp" + atritree = tkk.Treeview(container, columns=("#1"), selectmode="browse") + atritree.heading("#0", text=LH.string("attribute")) + atritree.heading("#1", text=LH.string("attribute-val")) + atritree.tag_bind("FA", "", halatribute) + atritree.tag_bind("OA", "", HMPC) + atritree.tag_bind("SID", "", copySID) + atritree.grid(row=2, column=0) + + #right click menu + rmenu = tk.Menu(container, tearoff=0) + rmenu.add_command(label=LH.string("rename"), command=renameobj) + rmenu.add_command(label=LH.string("delete"), command=delobj) + + objtree.bind("", rpopup) + + #menu init + menu = tk.Menu(container) + container.config(menu=menu) + filemenu = tk.Menu(menu) + menu.add_cascade(label=LH.string("file"), menu=filemenu) + filemenu.add_command(label=LH.string("new"), command=clear) + filemenu.add_command(label=LH.string("open"), command=load) + filemenu.add_command(label=LH.string("save"), command=save) + filemenu.add_separator() + #create logs var + clog = tk.BooleanVar() + filemenu.add_checkbutton(label=LH.string("clog"), onvalue=1, offvalue=0, variable=clog) + filemenu.add_separator() + filemenu.add_command(label=LH.string("export"), command=export) + filemenu.add_command(label=LH.string("import"), command=lambda: load(False)) + filemenu.add_separator() + filemenu.add_command(label=LH.string("exit"), command=container.quit) + + addmenu = tk.Menu(menu) + menu.add_cascade(label=LH.string("add"), menu=addmenu) + addmenu.add_command(label=LH.string("obj"), command=lambda: add("obj")) + addmenu.add_command(label=LH.string("script"), command=lambda: add("script")) + addmenu.add_command(label=LH.string("sound"), command=lambda: add("sound")) + addmenu.add_separator() + addmenu.add_command(label=LH.string("IPS"), command=importPS) + addmenu.add_command(label=LH.string("COBS"), command=lambda: COBS(acode(" "))) + #addmenu.add_command(label=LH.string("obj"), command=lambda: muladd("obj")) + + testmenu = tk.Menu(menu) + menu.add_cascade(label=LH.string("testing"), menu=testmenu) + testmenu.add_command(label=LH.string("test"), command=testing, image=icons["test"], compound="left") + testmenu.add_command(label=LH.string("stest"), command=stoptest, image=icons["stop-test"], compound="left") + + buildmenu = tk.Menu(menu) + menu.add_cascade(label=LH.string("building"), menu=buildmenu) + buildmenu.add_command(label=LH.string("build"), command=build, image=icons["build"], compound="left") + + langmenu = tk.Menu(menu) + menu.add_cascade(label=LH.string("langs"), menu=langmenu) + for i in LH.getlangs(): + langmenu.add_command(label=i, command=lambda i=i: selectlang(i)) + + container.mainloop() + +# attribute changers +def ats(mode, old): + #mode 0 = string + #mode 1 = single character + out = easygui.enterbox(LH.string("newval"), LH.string("newval")) + if out: + if mode == 1 and len(out) != 1: + messagebox.showerror(LH.string("error"), LH.string("SCE")) + return "N" + return out + else: + return old + +def anum(old): + out = easygui.enterbox(LH.string("newval"), LH.string("newval")) + if out: + if "." in out: + try: + out = float(out) + return out + except ValueError: + return old + else: + return int(out) + else: + return old + +def abool(old): + out = easygui.boolbox(LH.string("newval"), LH.string("newval"), (LH.string("true"), LH.string("false"))) + return out + +def acode(old): + out = easygui.textbox(LH.string("newval"), LH.string("newval"), old) + if out: + return out + else: + return old + +def apath(old, ext): + new = filedialog.askopenfilename(defaultextension=ext, filetypes=(ext)) + if new: + return new + else: + return old + +def aNULL(old): + return old + +def aposdone(): + global wait + wait = False + +def aposx(old): + global wait + wait = True + temp = tk.Toplevel() + butframe = tk.Frame(temp) + currentvar = tk.IntVar(temp, value=old) + current = tk.Entry(temp, textvariable=currentvar) + current.grid(row=0) + b1 = tk.Button(butframe, image=icons["ar-left"], command=lambda: currentvar.set(currentvar.get()-1)) + b2 = tk.Button(butframe, image=icons["ar-right"], command=lambda: currentvar.set(currentvar.get()+1)) + b1.grid(row=0, column=0) + b2.grid(row=0, column=1) + butframe.grid(row=1) + b3 = tk.Button(temp, text=LH.string("done"), command=aposdone) + b3.grid(row=3) + while wait == True: + temp.update() + tempvar = currentvar.get() + temp.destroy() + numbers = list(string.digits) + numbers.append("-") + for i in str(tempvar): + if not i in numbers: + return old + return tempvar + +def aposy(old): + global wait + wait = True + temp = tk.Toplevel() + butframe = tk.Frame(temp) + currentvar = tk.IntVar(temp, value=old) + current = tk.Entry(temp, textvariable=currentvar) + current.grid(row=0) + b1 = tk.Button(butframe, image=icons["ar-up"], command=lambda: currentvar.set(currentvar.get()-1)) + b2 = tk.Button(butframe, image=icons["ar-down"], command=lambda: currentvar.set(currentvar.get()+1)) + b1.grid(row=0, column=0) + b2.grid(row=1, column=0) + butframe.grid(row=1) + b3 = tk.Button(temp, text=LH.string("done"), command=aposdone) + b3.grid(row=3) + while wait == True: + temp.update() + tempvar = currentvar.get() + temp.destroy() + numbers = list(string.digits) + numbers.append("-") + for i in str(tempvar): + if not i in numbers: + return old + return tempvar + +def execgame(gametree, shouldlog=True): + global GUIe + global preview + global clog + global models + preview = hashengine.game(renderer=nullrend, sounddir="/") + GUIe = False + models = [] + load(False, False, "", str(gametree)) + clog = shouldlog + run() + +class rsound: + def __init__(self): + self.spath = "" + self.sdata = b"" + +class sound(): + def __init__(self, new): + self.spath = os.path.basename(new).split(".")[0] + self.sdata = hashengine.loadsound(new) + +global types +global ignoreat +global valtypes +global extypes +global attypes +global crucial +global DCTE +crucial = ["obj"] +types = hashengine.enum({"obj": hashengine.obj, "script": script, "rawsound": rsound, "sound": lambda: sound(apath("", [("Wave files", ".wave .wav")]))}) +ignoreat = ["ID", "execute", "sdata"] +DCTE = ["code"] +"""self.position = vector2() +self.char = " " +self.ID = 0 +self.gravity = 0 +self.acceleration = vector2() +self.velocity = vector2() +self.friction = 0 +self.collide = True +self.touch = True +self.anchored = False +self.bcolor = color3(255, 255, 255) +self.fcolor = color3()""" +valtypes = { +"char": lambda old: ats(1, old), +"gravity": anum, +"x": aposx, #anum +"y": aposy, #anum +"z": anum, +"r": anum, +"g": anum, +"b": anum, +"friction": anum, +"collide": abool, +"touch": abool, +"anchored": abool, +"code": acode, +"spath": aNULL, +} +#lambda old: apath(old, [("Wave files", ".wave .wav")]) +extypes = list(valtypes.keys()) +attypes = { +"vector2": hashengine.vector2, +"color3": hashengine.color3, +} +if __name__ == "__main__": + GUIinit() \ No newline at end of file diff --git a/tests/SEQTEST b/tests/SEQTEST new file mode 100644 index 0000000..8be57bc --- /dev/null +++ b/tests/SEQTEST @@ -0,0 +1 @@ +[[{'id': 'obj', 'name': 'Objekt', 'SID': 'cUwnltshBNeQQFvuwfXuUzsaHaJKyxSqwztnBteAIHrqzsOgEljfWOOGmzgCLgsuYxfyTyMehQXFcQWHCLmBWCMAPieboGymJOoNPKboUUtSuJUvjLLFYycsukzeHVBGcIUfZzJBJYUoFVTBhYKuLqYpwWrIWrEdUPjPpXUhKGEuolPGBHYmativzBekLKGEEKvpIWvPQoDhoAzVZaevzQAisacPettAjoEynVhDkSUggmsTjXqqutysffacbzD', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 0, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'SID': 'kzjhJQJZTwwBnsqFbMMWwoubynoPJVuFLPGlTMODHNbtIkqmYlCdwDQAgXEGrNemqizGeVajNuLScIftEjGfMgUVhFPYdXFDkKdyHJVdTascWZDJmZPmhTSiYWhnsvONfVvmHOmVeJrwHgjeHgDChAEkDXrDLbhoqVkpVvNaQgpecMqHaojBRGqlaDysXUYBSILmzOHbsllKaPxyPeGWNDTQkViUqdfPmfAYknybhPcGowVWzPaIijmbkFxYxyZ', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 1, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'obj', 'name': 'Objekt', 'SID': 'ypuYPxrQJbjLqPCIRSUjaSLKTjYRWFkldnHeHzaDuqTFcKbAVuqmKwadBqCrCyoNarxWlSCzIeeBpTIUCXNGWbMKtsmIsxUawwictmxqSRDwZyOdeqPYeMEeJaxwbpIovYpbHvbMglAfaOnQCXKqfStBXYURpfxUCrzDVnJzJMbuxWVHksdZQSjhChZTVAZrSChBrRQhkYCnsJqwxhEzrhjZgWIgaGopmAgQZnFFtQltSVovxbqvvTkquUEdswM', 'args': {'anchored': True, 'char': '#', 'collide': True, 'friction': 0, 'gravity': 0, 'acceleration': {'x': 0, 'y': 0, 'ARGID': 'vector2'}, 'bcolor': {'b': 255, 'g': 255, 'r': 255, 'ARGID': 'color3'}, 'fcolor': {'b': 0, 'g': 0, 'r': 0, 'ARGID': 'color3'}, 'position': {'x': 2, 'y': 5, 'ARGID': 'vector2'}, 'velocity': {'x': 0, 'y': 0, 'ARGID': 'vector2'}}}, {'id': 'script', 'name': 'Skript', 'SID': 'nWvowGAstSdSoUbpAoSoXlogKgfAApqyiiCEcfcEOUnCvthUiozkobNUlUNbiBdrzKdajEXAkrHbwQtGMExMWpDYoXRUVecdfvGYntJnKYdviiXSdcrsoTldVBOBQUgWylLBysTmVipXvBtyjOXOtvgrOqKWcdRjRNRhXqdNBRwCBrbpfHVxJIbGIttQZFYoypouuYexsLAwDtxlJdhZhYYpyQJTpJtGmLVFNcnJWUYejTDanpUfCVJZkfbRLXC', 'args': {'code': 'import time\nobj = HASHGAME.getobjseqbySID("cUwnlkzjhJypuYP")\ntime.sleep(3)\nobj.moveby(HASHBASE.vector2(0, 3))'}}], {'Erstellte Objekte': [0, 1, 2]}] \ No newline at end of file