DanisRace/run.py

668 lines
22 KiB
Python
Raw Permalink Normal View History

2024-07-13 15:15:50 +02:00
# GPL3 or any later version
# (C) J.Y.Amihud ( blenderdumbass ) 2024
# This is the launcher of the game.
import os
import subprocess
import time
import json
import threading
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib
from Scripts.Common import *
#### MAKING THE WINDOW ####
win = Gtk.Window()
win.set_title("Dani's Race")
win.set_size_request(799, 280)
win.connect("destroy", Gtk.main_quit)
win.set_default_icon_from_file("SettingUI/icon.png")
box = Gtk.VBox()
win.add(box)
#### Building the UI itself ###
banner = Gtk.Image.new_from_file('SettingUI/banner.jpg')
box.pack_start(banner, 0,0,0)
playbox = Gtk.HBox()
box.pack_end(playbox, 1,5,5)
def play(w):
data = load_settings()
if data:
blenderplayer = data.get("blenderplayer")
command = [blenderplayer]
if data.get("fullscreen"):
command.append("-f")
else:
command.append("-w")
command.append(data.get("resolution").split(":")[0])
command.append(data.get("resolution").split(":")[1])
# The file of the game
command.append(os.getcwd()+"/assembly.blend")
# print(command)
subprocess.Popen(command)
else:
set_settings(w)
playbutton = Gtk.Button("Start Game")
playbutton.connect("clicked", play)
playbox.pack_end(playbutton, 0,5,5)
################### SETTINGS #########################
def set_settings(w):
settingsWindow = Gtk.Dialog("Dani's Race Settings",
buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK),
)
settingsWindow.set_size_request(400, 400)
box = settingsWindow.get_content_area()
# Scroller
scrl = Gtk.ScrolledWindow()
box.pack_start(scrl, 1,1,1)
# Actuall useful box
box = Gtk.VBox()
scrl.add(box)
# UPBGE executable
upbgebox = Gtk.HBox()
upbgelabel = Gtk.Label("UPBGE executable: ")
upbgeinput = Gtk.Entry()
upbgeinput.set_text("blenderplayer")
upbgeinput.set_tooltip_text("Location of the blenderplayer executable on the system ( should in UPBGE folder ).")
upbgebox.pack_start(upbgelabel, 0,5,5)
upbgebox.pack_start(upbgeinput, 1,5,5)
box.pack_start(upbgebox, 0,5,5)
###### GRAPHICS / COMPLEXITY #####
box.pack_start(Gtk.Label("Graphics"), 0,5,5)
# Resolution
resbox = Gtk.HBox()
resfull = Gtk.CheckButton("Fullscreen")
resfull.set_tooltip_text("Whether to run the game Fullscreen.")
resmenu = Gtk.ComboBoxText()
resmenu.set_tooltip_text("What resolution to run the game at.")
resolutions = [
"7680:4320",
"5120:2880",
"3840:2160",
"2560:1440",
"1920:1080",
"1600:900",
"1366:768",
"1280:720",
"1024:576",
"960:540",
"854:480",
"640:360"
]
for i in resolutions:
resmenu.append_text(i)
resmenu.set_active(4)
resbox.pack_start(resfull, 0,5,5)
resbox.pack_end(resmenu, 0,5,5)
box.pack_start(resbox, 0,5,5)
# Compositing
compositor = Gtk.CheckButton("Post Processing Effects")
compositor.set_tooltip_text("Bloom, sun beams, film and color grading effects.")
compositor.set_active(True)
box.pack_start(compositor, 0,5,5)
# Reflections
reflections = Gtk.CheckButton("Screen-Space Reflections")
reflections.set_tooltip_text("Pseudo-accurate reflections.")
reflections.set_active(True)
box.pack_start(reflections, 0,5,5)
# Trees, Poles, Fenses
tplbox = Gtk.HBox()
trees = Gtk.CheckButton("Trees")
trees.set_tooltip_text("Whether to spawn Trees.")
trees.set_active(True)
poles = Gtk.CheckButton("Light Poles")
poles.set_tooltip_text("Whether to spawn Light Poles.")
poles.set_active(True)
fences = Gtk.CheckButton("Fences")
fences.set_tooltip_text("Whether to spawn Metal and or Wooden fences.")
fences.set_active(True)
tplbox.pack_start(trees, 1,5,5)
tplbox.pack_start(poles, 1,5,5)
tplbox.pack_start(fences, 1,5,5)
box.pack_start(tplbox, 0,5,5)
# Amount of cars
carsbox = Gtk.HBox()
carsbox.pack_start(Gtk.Label("Traffic Density"), 0,5,5)
maxcarsadjust = Gtk.Adjustment(4, lower=1, upper=20, step_increment=1)
maxcarsinput = Gtk.SpinButton(adjustment=maxcarsadjust, digits=0)
maxcarsinput.set_tooltip_text("How many NPC cars to spawn on roads.")
carsbox.pack_end(maxcarsinput, 0,5,5)
box.pack_start(carsbox, 0,5,5)
# Sampling
samplesbox = Gtk.HBox()
sampleslabel = Gtk.Label("Main Samples: ")
samplesadjust = Gtk.Adjustment(1, lower=1, upper=64, step_increment=1)
samplesinput = Gtk.SpinButton(adjustment=samplesadjust, digits=0)
samplesinput.set_sensitive(False)
samplesinput.set_tooltip_text("How many times to render the image per frame. More gives more accurate soft shadows and anti-aliasing. Less is faster.")
samplesbox.pack_start(sampleslabel, 0,5,5)
samplesbox.pack_end(samplesinput, 0,5,5)
box.pack_start(samplesbox, 0,5,5)
# Subsurface Sampling
skinsamplesbox = Gtk.HBox()
skinsampleslabel = Gtk.Label("Skin Samples: ")
skinsamplesadjust = Gtk.Adjustment(5, lower=1, upper=64, step_increment=1)
skinsamplesinput = Gtk.SpinButton(adjustment=skinsamplesadjust, digits=0)
skinsamplesinput.set_sensitive(False)
skinsamplesinput.set_tooltip_text("How accurate the subsurface materials ( skin ) should be. More, prettier, less faster.")
skinsamplesbox.pack_start(skinsampleslabel, 0,5,5)
skinsamplesbox.pack_end(skinsamplesinput, 0,5,5)
box.pack_start(skinsamplesbox, 0,5,5)
# Volumetric sampling
box.pack_start(Gtk.HSeparator(), 0,5,5) #############################
volumesamplesbox = Gtk.HBox()
volumesampleslabel = Gtk.Label("Volumetric Samples: ")
volumesamplesadjust = Gtk.Adjustment(32, lower=1, upper=64, step_increment=1)
volumesamplesinput = Gtk.SpinButton(adjustment=volumesamplesadjust, digits=0)
volumesamplesinput.set_tooltip_text("How accurate should be fog, smoke and fire effects. More prettier, less faster.")
volumesamplesbox.pack_start(volumesampleslabel, 0,5,5)
volumesamplesbox.pack_end(volumesamplesinput, 0,5,5)
box.pack_start(volumesamplesbox, 0,5,5)
# Volumetric lighting
volumelight = Gtk.CheckButton("Volumetric Lighting")
volumelight.set_active(True)
volumelight.set_tooltip_text("Enable light to interact with volumetric materials.")
box.pack_start(volumelight, 0,5,5)
# Volumetric shadow
def show_hide_volume_shadows(w):
volumeshadowsamplesbox.set_visible( w.get_active() )
volumeshadow = Gtk.CheckButton("Volumetric Shadows")
volumeshadow.set_active(False)
volumeshadow.set_tooltip_text("Enable volumetrics to cast shadows ( Very slow ).")
volumeshadow.connect("clicked", show_hide_volume_shadows)
box.pack_start(volumeshadow, 0,5,5)
# Volumetric shadow sampling
volumeshadowsamplesbox = Gtk.HBox()
volumeshadowsampleslabel = Gtk.Label("Volumetric Shadows Samples: ")
volumeshadowsamplesadjust = Gtk.Adjustment(3, lower=1, upper=64, step_increment=1)
volumeshadowsamplesinput = Gtk.SpinButton(adjustment=volumeshadowsamplesadjust, digits=0)
volumeshadowsamplesinput.set_tooltip_text("How accurate should be volumentric shadows. More prettier, less faster.")
volumeshadowsamplesbox.pack_start(volumeshadowsampleslabel, 0,5,5)
volumeshadowsamplesbox.pack_end(volumeshadowsamplesinput, 0,5,5)
box.pack_start(volumeshadowsamplesbox, 0,5,5)
# Shadows
box.pack_start(Gtk.HSeparator(), 0,5,5) #############################
def show_hide_shadows(w):
softshadows.set_visible( w.get_active() )
contactshadows.set_visible( w.get_active() )
shadowcubebox.set_visible( w.get_active() )
shadowcascadebox.set_visible( w.get_active() )
shadows = Gtk.CheckButton("Shadows")
shadows.set_active(True)
shadows.set_tooltip_text("Whether to render Shadows.")
shadows.connect("clicked", show_hide_shadows)
box.pack_start(shadows, 0,5,5)
# Soft Shadows
softshadows = Gtk.CheckButton("Soft Shadows")
softshadows.set_active(True)
softshadows.set_tooltip_text("Whether to try rendering soft Shadows. ( Requires more than one Sample )")
box.pack_start(softshadows, 0,5,5)
# Contact Shadows
contactshadows = Gtk.CheckButton("Contact Shadows")
contactshadows.set_active(True)
contactshadows.set_tooltip_text("Render a special pass of shadows to fill up small cracks.")
box.pack_start(contactshadows, 0,5,5)
# Shadow resolution
shadowresolutions = [
"4096",
"2048",
"1024",
"512",
"256",
"128",
"64"
]
shadowcubebox = Gtk.HBox()
shadowcubelabel = Gtk.Label("Lamp Shadow Resolution: ")
shadowcubemenu = Gtk.ComboBoxText()
for i in shadowresolutions:
shadowcubemenu.append_text(i)
shadowcubemenu.set_active(3)
shadowcubebox.pack_start(shadowcubelabel,0,5,5)
shadowcubebox.pack_end(shadowcubemenu,0,5,5)
box.pack_start(shadowcubebox, 0,5,5)
# Shadow cascade size
shadowcascadebox = Gtk.HBox()
shadowcascadelabel = Gtk.Label("Sun Shadow Resolution: ")
shadowcascademenu = Gtk.ComboBoxText()
for i in shadowresolutions:
shadowcascademenu.append_text(i)
shadowcascademenu.set_active(2)
shadowcascadebox.pack_start(shadowcascadelabel,0,5,5)
shadowcascadebox.pack_end(shadowcascademenu,0,5,5)
box.pack_start(shadowcascadebox, 0,5,5)
############ CONTROLS ########################
box.pack_start(Gtk.HSeparator(), 0,5,5) #############################
box.pack_start(Gtk.Label("Controls"), 0,5,5)
def show_hide_car_controls(w):
controlboxes["veh_forward"].set_visible( not w.get_active() )
controlboxes["veh_backward"].set_visible( not w.get_active() )
controlboxes["veh_left"].set_visible( not w.get_active() )
controlboxes["veh_right"].set_visible( not w.get_active() )
carmouseguides.set_visible( w.get_active() )
carmouseshow.set_visible( w.get_active() )
controlcarmouse = Gtk.CheckButton("Control Car With a Mouse")
controlcarmouse.connect("clicked", show_hide_car_controls )
controlcarmouse.set_tooltip_text("Use the mouse to control the car. Allows for more precise input. Has a learning curve.")
box.pack_start(controlcarmouse, 0,5,5)
carmouseguides = Gtk.CheckButton("Mouse Control Guides")
carmouseguides.set_active(True)
carmouseguides.set_tooltip_text("Show guides on the screen when controlling the car with the mouse.")
box.pack_start(carmouseguides, 0,5,5)
carmouseshow = Gtk.CheckButton("Show Mouse Cursor")
carmouseshow.set_tooltip_text("Show mouse cursor when controlling the car with the mouse. ( Easier to understand than the guides, but can obstruct the view ).")
box.pack_start(carmouseshow, 0,5,5)
controlnames = {
"veh_forward" :"Drive Forward",
"veh_backward" :"Drive Backward",
"veh_left" :"Steer Left",
"veh_right" :"Steer Right",
"veh_drift" :"Handbrake",
"veh_nitro" :"Use Nitro",
"veh_resque" :"Resque During Race",
"veh_gear_up" :"Shift Gears Up",
"veh_gear_down":"Shift Gears Down",
"veh_auto_gear":"Switch Automatic Gearbox",
"veh_dynamcam" :"Switch Dynamic Camera",
"veh_upload" :"Truck Deploy Cargo",
"chr_forward" :"Walk Forward",
"chr_backward" :"Walk Backward",
"chr_left" :"Walk Left",
"chr_right" :"Walk Right",
"chr_jump" :"Jump",
"chr_get_car" :"Enter Car",
"chr_swimdown" :"Swim Down"
}
controldefaults = {
"veh_forward" :"UpArrow",
"veh_backward" :"DownArrow",
"veh_left" :"LeftArrow",
"veh_right" :"RightArrow",
"veh_drift" :"Space",
"veh_nitro" :"Z",
"veh_resque" :"BackSpace",
"veh_gear_up" :"W",
"veh_gear_down":"S",
"veh_auto_gear":"Q",
"veh_dynamcam" :"C",
"veh_upload" :"D",
"chr_forward" :"W",
"chr_backward" :"S",
"chr_left" :"A",
"chr_right" :"D",
"chr_jump" :"Space",
"chr_get_car" :"Enter",
"chr_swimdown" :"LShift"
}
controlwidgets = {}
controlboxes = {}
for control in controlnames:
cbox = Gtk.HBox()
box.pack_start(cbox, 0,5,5)
controlboxes[control] = cbox
cbox.pack_start(Gtk.Label(controlnames[control]), 0,5,5)
controlwidgets[control] = Gtk.ComboBoxText()
cbox.pack_end(controlwidgets[control], 0,5,5)
for key in keycodes:
controlwidgets[control].append_text(key)
controlwidgets[control].set_active( list(keycodes.keys()).index(controldefaults[control]) )
######## NETWORK ######
box.pack_start(Gtk.HSeparator(), 0,5,5) #############################
box.pack_start(Gtk.Label("Multiplayer"), 0,5,5)
def show_hide_multiplayer(w):
hostbox.set_visible( w.get_active() )
usernamebox.set_visible( w.get_active() )
multiplayerroombox.set_visible( w.get_active() )
multiplayer = Gtk.CheckButton("Multiplayer")
multiplayer.connect("clicked", show_hide_multiplayer)
box.pack_start(multiplayer, 0,5,5)
hostbox = Gtk.HBox()
hostbox.pack_start(Gtk.Label("Hostname:"), 0,5,5)
hostname = Gtk.Entry()
hostbox.pack_end(hostname, 0,5,5)
box.pack_start(hostbox, 0,5,5)
usernamebox = Gtk.HBox()
usernamebox.pack_start(Gtk.Label("Username:"),0,5,5)
username = Gtk.Entry()
usernamebox.pack_end(username,0,5,5)
box.pack_start(usernamebox, 0,5,5)
multiplayerroombox = Gtk.HBox()
multiplayerroombox.pack_start(Gtk.Label("Room:"),0,5,5)
multiplayerroom = Gtk.Entry()
multiplayerroombox.pack_end(multiplayerroom,0,5,5)
box.pack_start(multiplayerroombox, 0,5,5)
######### TIME ########
box.pack_start(Gtk.HSeparator(), 0,5,5) #############################
box.pack_start(Gtk.Label("In Game Time"), 0,5,5)
clockspeedbox = Gtk.HBox()
clockspeedbox.pack_start(Gtk.Label("In Game Clock Speed:"), 0,5,5)
clockspeedadjustment = Gtk.Adjustment(20, lower=0.1, upper=10000, step_increment=0.1)
clockspeedentry = Gtk.SpinButton(adjustment=clockspeedadjustment, digits=2)
clockspeedentry.set_tooltip_text("How much the clock in the game is faster than the real clock. 1 is real time speed. 10 is ten times faster.")
clockspeedbox.pack_end(clockspeedentry, 0,5,5)
box.pack_start(clockspeedbox, 0,5,5)
############################################# DEV SETTINGS #####################
box.pack_start(Gtk.HSeparator(), 0,5,5) #############################
box.pack_start(Gtk.Label("For Developers"), 0,5,5)
def show_hide_devmode(w):
devmode_cheats.set_visible( w.get_active() )
devmode_visible_rays.set_visible( w.get_active() )
if not w.get_active():
devmode_cheats.set_active( False )
devmode_visible_rays.set_active( False )
devmode = Gtk.CheckButton("Developer Mode")
devmode.set_tooltip_text("Developer mode is mode used in development of the game.")
box.pack_start(devmode, 0,5,5)
devmode.connect("clicked", show_hide_devmode )
devmode_cheats = Gtk.CheckButton("Developer Keyboard Cheatcodes")
devmode_cheats.set_tooltip_text("Enable keyboards cheat codes, for testing purposes.")
box.pack_start(devmode_cheats, 0,5,5)
devmode_visible_rays = Gtk.CheckButton("Developer Visible Rays")
devmode_visible_rays.set_tooltip_text("Show the rays that are used for AIs to see.")
box.pack_start(devmode_visible_rays, 0,5,5)
################################################################################
# Loading settings
data = load_settings()
if data:
upbgeinput.set_text( data.get("blenderplayer", "blenderplayer") )
resfull.set_active( data.get("fullscreen", False ) )
resmenu.set_active( resolutions.index( data.get("resolution", "1920:1080" ) ) )
compositor.set_active( data.get("compositor", True ) )
reflections.set_active( data.get("reflections", True ) )
trees.set_active( data.get("trees", True ) )
poles.set_active( data.get("poles", True ) )
fences.set_active( data.get("fences", True ) )
samplesadjust.set_value( data.get("samples", 1 ) )
skinsamplesadjust.set_value( data.get("skinsamples", 5 ) )
volumesamplesadjust.set_value( data.get("volumesamples", 32 ) )
volumelight.set_active( data.get("volumelight", True ) )
volumeshadow.set_active( data.get("volumeshadow", False ) )
volumeshadowsamplesadjust.set_value( data.get("volshadsampl", 3 ) )
shadows.set_active( data.get("shadows", True ) )
softshadows.set_active( data.get("softshadows", True ) )
contactshadows.set_active( data.get("cntctshadows", True ) )
shadowcubemenu.set_active( shadowresolutions.index( data.get("shadowslamps", "512" ) ) )
shadowcascademenu.set_active( shadowresolutions.index( data.get("shadowssun", "1024" ) ) )
devmode.set_active( data.get("devmode", False ) )
devmode_cheats.set_active( data.get("dev-cheats", False ) )
devmode_visible_rays.set_active(data.get("dev-rays", False ) )
clockspeedadjustment.set_value( data.get("clockspeed", 20.0 ) )
controlcarmouse.set_active( data.get("veh_mouse", False ) )
maxcarsadjust.set_value( data.get("maxcars", 4 ) )
carmouseguides.set_active( data.get("veh_mouse_guides",True ) )
carmouseshow.set_active( data.get("veh_mouse_cursor",False ) )
multiplayer.set_active( data.get("multiplayer", False ) )
hostname.set_text( data.get("mp-host", "http://localhost:6969") )
username.set_text( data.get("mp-name", "Dani" ) )
multiplayerroom.set_text( data.get("mp-room", "Main" ) )
for control in controlwidgets:
try:
controlwidgets[control].set_active( list(keycodes.keys()).index(data.get(control)) )
except:
controlwidgets[control].set_active( list(keycodes.keys()).index(controldefaults[control]) )
settingsWindow.show_all()
show_hide_shadows(shadows)
show_hide_volume_shadows(volumeshadow)
show_hide_devmode(devmode)
show_hide_car_controls(controlcarmouse)
show_hide_multiplayer(multiplayer)
response = settingsWindow.run()
if response == Gtk.ResponseType.OK:
folder = get_settings_folder()
f = folder+"/config.json"
data = {"blenderplayer":upbgeinput.get_text(),#
"fullscreen" :resfull.get_active(),#
"resolution" :resmenu.get_active_text(),#
"compositor" :compositor.get_active(),#
"reflections" :reflections.get_active(),#
"trees" :trees.get_active(),#
"poles" :poles.get_active(),#
"fences" :fences.get_active(),#
"samples" :int(samplesadjust.get_value()),#
"skinsamples" :int(skinsamplesadjust.get_value()),#
"volumesamples":int(volumesamplesadjust.get_value()),#
"volumelight" :volumelight.get_active(),#
"volumeshadow" :volumeshadow.get_active(),#
"volshadsampl" :int(volumeshadowsamplesadjust.get_value()),#
"shadows" :shadows.get_active(), #
"softshadows" :softshadows.get_active(),#
"cntctshadows" :contactshadows.get_active(),#
"shadowslamps" :shadowcubemenu.get_active_text(),#
"shadowssun" :shadowcascademenu.get_active_text(), #
"devmode" :devmode.get_active(),
"dev-cheats" :devmode_cheats.get_active(),
"dev-rays" :devmode_visible_rays.get_active(),
"clockspeed" :clockspeedadjustment.get_value(),
"veh_mouse" :controlcarmouse.get_active(),
"maxcars" :int(maxcarsadjust.get_value()),
"veh_mouse_guides":carmouseguides.get_active(),
"veh_mouse_cursor":carmouseshow.get_active(),
"multiplayer" :multiplayer.get_active(),
"mp-host" :hostname.get_text(),
"mp-name" :username.get_text(),
"mp-room" :multiplayerroom.get_text()
}
for control in controlwidgets:
data[control] = controlwidgets[control].get_active_text()
with open(f, "w") as save:
json.dump(data, save, indent=4, sort_keys=True)
settingsWindow.destroy()
settingsbutton = Gtk.Button("Settings")
settingsbutton.connect("clicked", set_settings)
settingsbutton.set_relief(Gtk.ReliefStyle.NONE)
playbox.pack_end(settingsbutton, 0,5,5)
def get_settings_folder():
game = "danisrace"
try:
data_dir = os.environ["XDG_DATA_HOME"] + "/" + game
except:
data_dir = os.path.expanduser("~/.local/share/"+game)
try:
os.makedirs(data_dir)
except:
pass
return data_dir
def load_settings():
folder = get_settings_folder()
f = folder+"/config.json"
try:
with open(f) as o:
return json.load(o)
except: return None
#### Launching he ui ######
win.show_all()
Gtk.main()