hashhub/main.py

525 lines
15 KiB
Python

import sys
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 PCPL
import langsys
import ast
import subprocess
import sys
import time
import hashengine
import shutil
import os
import random
import string
import easygui
global LH
global gamedata
global cooldown
cooldown = False
gamedata = {}
LH = langsys.langhandler()
lang = open("clang", 'r')
lang = lang.read()
LH.setlang(lang)
# LH.string("")
PCPL.interpreter.ENG = hashengine
def prepgamedata():
out = []
tempwin = tk.Tk()
bar = tkk.Progressbar(tempwin)
bar.place(width=200)
ptext = tk.Label(tempwin, text="NONE")
ptext.place()
count = 1
for i in gamedata:
i = gamedata[i]
ptext.config(text=i["name"])
bar.step(count/len(gamedata))
count += 1
tempwin.update()
temp = {"id": i["id"], "name": i["name"]}
tempargs = {}
tosearch = {}
for arg in i["args"]:
if not arg in extypes and not arg in ignoreat:
tosearch[arg] = i["args"][arg]
continue
if arg in ignoreat: continue
tempargs[arg] = i["args"][arg]
for argname in tosearch:
arg = tosearch[argname]
temp2 = getattributes(arg)
temp2.update({"ARGID": arg._type})
tempargs[argname] = temp2
temp["args"] = tempargs
out.append(temp)
tempwin.destroy()
return out
class script:
def __init__(self):
self.code = ""
def execute(self, API):
#old code for PCPL code execution, replaced with python code execution
"""
PCPL.resetvar()
PCPL.LIS("HASHBASE")
PCPL.run(self.code)"""
exec(self.code, API)
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)
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 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))
def selectlang(new):
lang = open("clang", 'w')
lang.write(new)
lang.close()
container.quit()
subprocess.Popen([sys.executable, __file__])
def add(objtype):
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)}
id = ""
chars = list(string.ascii_letters)
for i in range(255):
id = id + random.choice(chars)
objtree.insert("", 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
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)
gamedata[target]["name"] = new
def delobj():
target = objtree.focus()
if target == "": return
atritree.delete(*atritree.get_children())
objtree.delete(target)
temp = gamedata.pop(target)
if temp["id"] in crucial:
preview.removeobjbyid(temp["args"]["ID"])
preview.render()
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 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:
val = gamedata[target]["args"][i]
atritree.insert("", tk.END, text=i, values=(val))
else:
root = atritree.insert("", tk.END, text=i)
temp = getattributes(gamedata[target]["args"][i])
for f in temp:
atritree.insert(root, tk.END, text=f, values=(temp[f]))
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)
atritree.item(target, values=(new))
else:
parent = atritree.item(parent, "text")
new = valtypes[name](getattr(gamedata[currentat]["args"][parent], name))
setattr(gamedata[currentat]["args"][parent], name, new)
atritree.item(target, values=(new))
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(prepgamedata()))
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 importobj(target):
oid = add(target["id"])
id = gamedata[oid]
id["name"] = target["name"]
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)
def load():
file = filedialog.askopenfile()
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()
target = ast.literal_eval(target)
clear()
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()
def log(text, end="\n", flush=False):
global logfile
file = open("logs/"+logfile+".txt", 'a')
file.write(text+end)
file.close()
def NULL():
pass
def testing():
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("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: previewrend(size, cam, window, [0, 0]))
API["HASHGAME"] = maingame
log("main game initalised!")
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)
for i in scripts:
maingame.startscript(lambda: i.execute(API))
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("game test started!!!")
log("---------------------")
def muladd(target):
for i in range(10):
add(target)
def stoptest():
maingame.stopscripts()
window.destroy()
def build():
print("asking user for output directory...")
target = filedialog.askdirectory()
print("building started")
print("generating HEGF file...")
hegf = str(prepgamedata())
file = open(target+"/game.HEGF", 'w')
file.write(hegf)
file.close()
print("done.")
print("copying files...")
tocopy = ["mtTkinter.py", "player.py", "hashengine.py"]
for i in tocopy:
print(f"copying {i}...")
shutil.copyfile(i, target+"/"+i)
print("done.")
print("building finished!")
def GUIinit():
global container
global objtree
global rmenu
global atritree
global currentat
global preview
container = tk.Tk()
container.bind("<KeyPress>", updatepreviewcam)
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]))
#tree init
objtree = tkk.Treeview(container, selectmode="browse", columns=("-"))
objtree.heading("#0", text=LH.string("objs"))
objtree.tag_bind("objsel", "<<TreeviewSelect>>", updatribute)
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.bind("<Double-1>", halatribute)
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("<Button-3>", 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()
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("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")))
if out:
return out
else:
return old
def acode(old):
out = easygui.textbox(LH.string("newval"), LH.string("newval"), old)
if out:
return out
else:
return old
global types
global ignoreat
global valtypes
global extypes
global attypes
global crucial
crucial = ["obj"]
types = hashengine.enum({"obj": hashengine.obj, "script": script})
ignoreat = ["ID", "execute"]
"""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": anum,
"y": anum,
"z": anum,
"r": anum,
"g": anum,
"b": anum,
"friction": anum,
"collide": abool,
"touch": abool,
"anchored": abool,
"code": acode,
}
extypes = list(valtypes.keys())
attypes = {
"vector2": hashengine.vector2,
"color3": hashengine.color3,
}
GUIinit()