Skip to content

Commit ee474be

Browse files
committed
port ott stuff
eventually i should make this a submodule
1 parent 52c0b5b commit ee474be

File tree

7 files changed

+207
-33
lines changed

7 files changed

+207
-33
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,4 @@ phase_*/
136136
build.py
137137
*.bat
138138
ttle_dist.py
139+
leveleditor/settings.json

toontown/leveleditor/OTTUtil.py renamed to ott/OTTUtil.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
'''
1+
"""
22
Helpers and such for Open Toontown Tools
3-
'''
3+
"""
4+
from direct.task.TaskManagerGlobal import taskMgr
45

56

6-
def sleep(duration):
7-
'''
7+
def sleep(duration: float):
8+
"""
89
Breaks for a number of seconds. Returns an awaitable.
910
@LittleToonCat
10-
'''
11+
12+
:param duration: Duration of sleep
13+
"""
1114

1215
def __task(task):
1316
if task.time > duration:

ott/Settings.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
OpenTTTools Settings
3+
Slight override of a typical dict to make the file auto save when a change is made
4+
"""
5+
6+
import collections
7+
import json
8+
import os
9+
10+
11+
class Settings(collections.MutableMapping):
12+
13+
def __init__(self, filename: str):
14+
"""
15+
:param filename: File path to json file
16+
"""
17+
self.filename = filename
18+
19+
self.data = {}
20+
21+
# Make sure the file exists
22+
if os.path.exists(self.filename):
23+
try:
24+
with open(self.filename, 'r') as f:
25+
self.data = json.load(f)
26+
except:
27+
# Something went wrong with the file, probable corruption, make a new one
28+
self.save()
29+
# If not, create it
30+
else:
31+
self.save()
32+
33+
def save(self):
34+
"""
35+
Write settings changes to the json file
36+
"""
37+
with open(self.filename, 'w') as jsonFile:
38+
json.dump(self.data, jsonFile, indent = 4)
39+
print('Saved settings')
40+
41+
''' Overrides '''
42+
43+
def __getitem__(self, key: str):
44+
"""
45+
x = settings['setting'] override
46+
47+
:param key: Setting Key
48+
:return: Setting value
49+
"""
50+
return self.data[key]
51+
52+
def __setitem__(self, key: str, value: str):
53+
"""
54+
settings['setting'] = 'value' override
55+
56+
:param key: Setting Key
57+
:param value: The value to set the setting to
58+
"""
59+
self.data[key] = value
60+
# Save the file
61+
self.save()
62+
63+
def __delitem__(self, key: str):
64+
"""
65+
del settings['setting'] override
66+
67+
:param key: Setting Key to remove
68+
"""
69+
del self.data[key]
70+
# Save the file
71+
self.save()
72+
73+
def __iter__(self):
74+
"""
75+
iteration override (e.g. for x in settings)
76+
77+
:return: Iterable of settings
78+
"""
79+
return iter(self.data)
80+
81+
def __len__(self) -> int:
82+
"""
83+
len(settings) Override
84+
85+
:return: Number of settings as integer
86+
"""
87+
return len(self.data)

ott/ShaderRegistry.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
Shader Registry - drewcification 111420
3+
Static class to register and get shaders
4+
5+
Shaders are registered at the games initialization
6+
from ott.ShaderRegistry import ShaderRegistry
7+
ShaderRegistry.register('render:black_and_white',
8+
frag = 'phase_3/shaders/tt_sha_render_bandw.frag',
9+
vert = 'phase_3/shaders/tt_sha_render_bandw.vert')
10+
11+
They can be retrieved at any point during runtime
12+
from ott.ShaderRegistry import ShaderRegistry
13+
render.setShader(ShaderRegistry.get('render:black_and_white'))
14+
"""
15+
16+
from panda3d.core import Shader
17+
18+
19+
class ShaderRegistry:
20+
# Static shader dictionary
21+
shaders = {}
22+
23+
@staticmethod
24+
def register(identifier: str, frag: str, vert: str):
25+
"""
26+
Register shader
27+
28+
All shaders must be in GLSL with separate .frag and .vert files!
29+
30+
Shader identifiers should be formatted by where they are used
31+
32+
e.g.:
33+
Full scene render effects are prefixed with 'render:'
34+
CheesyEffects are prefixed with 'ce:'
35+
Make-A-Toon shaders are prefixed with 'mat:'
36+
etc.
37+
38+
:param identifier: Identifier string
39+
:param frag: Fragment shader file path
40+
:param vert: Vertex shader file path
41+
"""
42+
shader = Shader.load(Shader.SL_GLSL, fragment = frag, vertex = vert)
43+
ShaderRegistry.shaders[identifier] = shader
44+
print(f'Registered shader {identifier}')
45+
46+
@staticmethod
47+
def get(identifier: str) -> Shader:
48+
"""
49+
Returns loaded shader
50+
51+
:param identifier:
52+
:return: Shader
53+
"""
54+
55+
# Raise an exception if we load a shader we haven't registered yet
56+
if identifier not in ShaderRegistry.shaders:
57+
raise NotInRegistryError(identifier)
58+
59+
return ShaderRegistry.shaders.get(identifier)
60+
61+
62+
class NotInRegistryError(Exception):
63+
def __init__(self, identifier: str):
64+
self.identifier = identifier
65+
66+
def __str__(self):
67+
return f'identifier {self.identifier} not in registry'

ott/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
""" Universal classes for all OTT Projects """

toontown/leveleditor/LevelEditorGlobals.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,16 @@
191191
DNA_WALL,
192192
DNA_WINDOWS]
193193

194-
DNA_PROP_SETS = {'tree': ["prop_tree_small_ul",
195-
"prop_tree_small_ur",
196-
"prop_tree_large_ur",
197-
"prop_tree_large_ul"],
194+
DNA_PROP_SETS = {'tree': ["prop_tree_small_ul",
195+
"prop_tree_small_ur",
196+
"prop_tree_large_ur",
197+
"prop_tree_large_ul"],
198198
'snow_tree': ["prop_snow_tree_small_ul",
199-
"prop_snow_tree_small_ur",
200-
"prop_snow_tree_large_ur",
201-
"prop_snow_tree_large_ul"]}
199+
"prop_snow_tree_small_ur",
200+
"prop_snow_tree_large_ur",
201+
"prop_snow_tree_large_ul"]
202+
}
203+
202204
CONTROLS = '''
203205
--Camera--
204206
Note: All camera transformations orbit the currently selected object

ttle.py

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
""" OpenLevelEditor Base Class - Drewcification 091420 """
22

3+
import argparse
4+
import asyncio
5+
import builtins
6+
import os
7+
import pathlib
8+
import sys
39
from direct.directnotify.DirectNotifyGlobal import directNotify
4-
from direct.showbase.ShowBase import ShowBase
510
from direct.gui.OnscreenText import OnscreenText
6-
11+
from direct.showbase.ShowBase import ShowBase
712
from panda3d.core import loadPrcFile, loadPrcFileData
8-
913
from tkinter import Tk, messagebox
10-
from toontown.toonbase import ToontownGlobals
1114

12-
import asyncio
13-
import argparse
14-
import builtins
15-
import os
16-
import sys
15+
from ott.Settings import Settings
16+
from toontown.toonbase import ToontownGlobals
1717

1818
TOONTOWN_ONLINE = 0
1919
TOONTOWN_REWRITTEN = 1
@@ -28,6 +28,12 @@
2828

2929
DEFAULT_SERVER = TOONTOWN_ONLINE
3030

31+
DEFAULT_SETTINGS = {
32+
'autosave-enabled': True,
33+
'autosave-interval': 15,
34+
'autosave-max-files': 10,
35+
'fps-meter-update-rate': 0
36+
}
3137

3238
class ToontownLevelEditor(ShowBase):
3339
notify = directNotify.newCategory("Open Level Editor")
@@ -44,18 +50,24 @@ def __init__(self):
4450
if not os.path.exists(userfiles):
4551
pathlib.Path(userfiles).mkdir(parents = True, exist_ok = True)
4652

53+
builtins.settings = Settings(f'{userfiles}/settings.json')
54+
55+
for setting in DEFAULT_SETTINGS:
56+
if setting not in settings:
57+
settings[setting] = DEFAULT_SETTINGS[setting]
58+
4759
# Check for -e or -d launch options
4860
parser = argparse.ArgumentParser(description = "Modes")
4961
parser.add_argument("--experimental", action = 'store_true', help = "Enables experimental features")
5062
parser.add_argument("--debug", action = 'store_true', help = "Enables debugging features")
5163
parser.add_argument("--noupdate", action = 'store_true', help = "Disables Auto Updating")
52-
parser.add_argument("--png", action = 'store_true', help = "Forces PNG resources mode, if this is not specified, "
53-
"it will automatically determine the format")
64+
parser.add_argument("--png", action = 'store_true', help = "Forces PNG resources mode, if this is not "
65+
"specified, it will automatically determine the "
66+
"format")
5467
parser.add_argument("--compiler", nargs = "*",
5568
help = "Specify which compiler to use (Only useful if your game uses a form of "
5669
"libpandadna.) Valid options are 'libpandadna', for games which use the "
57-
"modern c++ version of libpandadna, and 'clash', "
58-
"for Corporate Clash")
70+
"modern c++ version of libpandadna, and 'clash', for Corporate Clash")
5971

6072
parser.add_argument("--server", nargs = "*", help = "Enables features exclusive to various Toontown projects",
6173
default = 'online')
@@ -151,21 +163,21 @@ def updateFrameRateMeter(self, task):
151163
"""
152164
fps = globalClock.getAverageFrameRate()
153165

154-
# Color is green by default
155-
color = (0, 0.9, 0, 1)
156-
157-
# At or below 45 fps is yellow
158166
if fps <= 45:
167+
# At or below 45 fps is yellow
159168
color = (1, 0.9, 0, 1)
160-
# At or below 30 fps is red
161169
elif fps <= 30:
170+
# At or below 30 fps is red
162171
color = (1, 0, 0, 1)
172+
else:
173+
# Color is green by default
174+
color = (0, 0.9, 0, 1)
163175

164176
text = f'{round(fps, 1)} FPS'
165177
self.frameRateMeter.setText(text)
166178
self.frameRateMeter.setFg(color)
167-
168-
return task.cont
179+
task.delayTime = settings['fps-meter-update-rate']/1000
180+
return task.again
169181

170182
def __checkForFiles(self):
171183
# Make custom hood directory if it doesn't exist
@@ -194,7 +206,8 @@ def __createTk(self):
194206

195207
self.tkRoot = tkroot
196208

197-
def __addCullBins(self):
209+
@staticmethod
210+
def __addCullBins():
198211
cbm = CullBinManager.getGlobalPtr()
199212
cbm.addBin('ground', CullBinManager.BTUnsorted, 18)
200213
cbm.addBin('shadow', CullBinManager.BTBackToFront, 19)

0 commit comments

Comments
 (0)