import bge import bpy import json import os import aud import time import datetime import threading import random import numpy import math import mathutils from Scripts import Reuse from Scripts import Destruction from Scripts import Opt from Scripts.Common import * from Scripts import Map from Scripts import Script from Scripts import Vehicle from Scripts import Settings from Scripts import Tools from Scripts import Money from Scripts import Garage from Scripts import Racing from Scripts import Character_Controll from Scripts import Multiplayer_Client def main(): # SPAWNING ASSETS AND STUFF spawnAtDistance = 250 maxCars = 6 scene = bge.logic.getCurrentScene() cont = bge.logic.getCurrentController() dani = scene.objects["Dani_Box"] cam = scene.active_camera #dani["driving"]["nitro"] = 10.0 #Script.Story["Jack"].position = dani.position #Character_Controll.getOutCar(Script.Story["Jack"]) #Script.Story["DarkShadow"] = dani["driving"] # try: # Destruction.Explosion(dani["driving"].position, mass=10, size=10) # except:pass loading = scene.objects["Loading"] if not loading.get("loaded"): loading.scaling = [1,1,1] loading["loaded"] = True return if "fps-calc" not in bge.logic.globalDict: bge.logic.globalDict["fps-calc"] = {"second":0, "fps-list":[]} Opt.ExecuteScheduled() goodFPS = Opt.GoodFPS(traceback=True) fpsindicator = int(Opt.GoodFPS( boolean=False)*100) scene.objects["Dani_Fps_Good_Indicator"]["Text"] = str(int(bge.logic.getAverageFrameRate()))+"\n"+str(fpsindicator)+"%" scene.objects["Gage_FPS"]["Health"] = fpsindicator #camSurround = Opt.Surround(cam.position, spawnAtDistance/2)#, cam.orientation.to_euler()) camSurroundCars = Opt.Surround(cam.position, spawnAtDistance, cam.orientation.to_euler()) #changedCamSurround = Opt.SurroundChanged("camSurround", camSurround) #changedCamSurroundCars = Opt.SurroundChanged("camSurroundCars", camSurroundCars) inCinema = scene.objects["CinemaColider"]["InCinema"] # Destroy those needing destroying Reuse.SelfDestructDo() # Available car to spawn # NPC_cars = ["NeonSpeedsterBox", # "RedKissBox", # "DarkShadowBox"] # #"HatchBack01-white", # #"HatchBack01-orange", # #"HatchBack01-blue", # #"HatchBack01-black"] # npccp = [1, # 1, # 1] # #10, # #8, # #5, # #3] # NPC_cars_probability = [] # for i in npccp: # NPC_cars_probability.append( 1 / sum(npccp) * i) #print(sum(NPC_cars_probability), NPC_cars_probability) # Storing some values to the globalDict bge.logic.globalDict["spawnAtDistance"] = spawnAtDistance bge.logic.globalDict["maxCars"] = maxCars def GenerateDoorObject(i): # Location doesn't matter when you dealing with rotation doorObject = {"ClosedRotX":i.get("ClosedRotX", i.orientation.to_euler()[0]), "ClosedRotY":i.get("ClosedRotY", i.orientation.to_euler()[1]), "ClosedRotZ":i.get("ClosedRotZ", i.orientation.to_euler()[2]), "OpenRotX":i.get("OpenRotX", i.orientation.to_euler()[0]), "OpenRotY":i.get("OpenRotY", i.orientation.to_euler()[1]), "OpenRotZ":i.get("OpenRotZ", i.orientation.to_euler()[2]), "ClosedLocX":i.get("ClosedLocX", i.position[0]), "ClosedLocY":i.get("ClosedLocY", i.position[1]), "ClosedLocZ":i.get("ClosedLocZ", i.position[2]), "door": i } # But rotation and location both matter when you dealing with location move = [0,0,0] moveback = [0,0,0] for naxis, axis in enumerate(["X", "Y", "Z"]): code = "OpenLoc"+axis move[naxis] = i.get(code, 0) moveback[naxis] = -i.get(code, 0) i.applyMovement(move, True) for naxis, axis in enumerate(["X", "Y", "Z"]): code = "OpenLoc"+axis doorObject[code] = i.position[naxis] i.applyMovement(moveback, True) return doorObject def OpenCloseDoor(door, openClose): onTarget = [] axislist = ["X", "Y", "Z"] for axis in axislist: n = ["X", "Y", "Z"].index(axis) targetRot = door[openClose+"Rot"+axis] targetLoc = door[openClose+"Loc"+axis] dRot = door["door"].orientation.to_euler() onRotTarget = round(targetRot, 2) == round(dRot[n], 2) onLocTraget = round(targetLoc, 1) == round(door["door"].position[n], 1) if not onRotTarget: dRot[n] += (targetRot - dRot[n])/15 else: dRot[n] = targetRot door["door"].orientation = dRot if not onLocTraget: door["door"].position[n] += (targetLoc - door["door"].position[n])/15 else: door["door"].position[n] = targetLoc onTarget.append( onRotTarget and onLocTraget ) return all( onTarget ) # INITIALIZING # This runs only on the first frame if not Opt.chunks: dani.suspendPhysics() # Making settings executed Settings.Execute() settings = Settings.load_settings() bge.logic.globalDict["settings"] = settings Settings.LoadGame() Script.StatusText(" ") if not bge.logic.globalDict.get("start-time"): bge.logic.globalDict["start-time"] = datetime.datetime.now().hour + datetime.datetime.now().minute / 60 # Stuff bge.logic.globalDict["netObjects"] = { "pythonId":{}, "netId":{} } bge.logic.globalDict["elevators"] = {} bge.logic.globalDict["sound-ambiances"] = [] bge.logic.globalDict["doors"] = {} bge.logic.globalDict["races"] = {} bge.logic.globalDict["garage-crates"] = [] # Cars related bge.logic.globalDict["spawns"] = {} bge.logic.globalDict["allcars"] = [] bge.logic.globalDict["cars"] = [] bge.logic.globalDict["spawnedCarModels"] = [] # Cheat code modes bge.logic.globalDict["pursuit-cheat"] = False bge.logic.globalDict["derby-cheat"] = False bge.logic.globalDict["gravity"] = True # Navigation for NPCs bge.logic.globalDict["Navigation"] = {"road" :[], "parking":[]} Navigation = bge.logic.globalDict["Navigation"] for navtag in bpy.data.collections["Navigation"].objects: tagdata = {"position":navtag.location, "orientation":navtag.rotation_euler, "radius":navtag.scale[0], "connected":[]} if navtag.get("parking"): Navigation["parking"].append(tagdata) else: Navigation["road"].append(tagdata) # Races for collection in bpy.data.collections['Races'].children: race = {"starters":[], "checkpoints":[], "racers":[], "racer_spawns": [], "started":False } # Getting racing data rdf = os.listdir(bge.logic.expandPath("//racedata")) if collection.name in rdf: fol = "//racedata/"+collection.name race["raceData"] = {} for f in os.listdir(bge.logic.expandPath(fol)): if f.endswith(".json"): with open(bge.logic.expandPath(fol+"/"+f)) as jf: rd = json.load(jf) race["raceData"][f.replace(".json", "")] = rd for object in collection.objects: tag = {"location":object.location, "rotation":object.rotation_euler, "radius":object.scale[0], "OnLoop":object.get("OnLoop"), "IgnoreVision":object.get("IgnoreVision"), "Uturn":object.get("Uturn"), "cylinder":None} # Race starters ( the blue cylinder ) if object.name.startswith("Starter"): race["starters"].append(tag) race["laps"] = object["laps"] race["after"] = object.get("after") race["during"] = object.get("during") race["type"] = object.get("type", "race-car") race["reward"] = object.get("reward", 1000) race["TimeRange"] = list(object.get("TimeRange",[])) # Race checkpoints ( the yellow cylinder ) else: race["checkpoints"].append(tag) bge.logic.globalDict["races"][collection.name] = race print(collection.name, race["TimeRange"]) # Characters Reuse.Delete(scene.objects["PapsBox"]) #Reuse.Delete(scene.objects["MoriaBox"]) Reuse.Delete(scene.objects["JackBox"]) # Objects for object in scene.objects: if "spawn" in object: objectData = {"position": object.worldPosition.copy(), "orientation": object.worldOrientation.copy(), "spawn": object.get("spawn"), "to_spawn": object["to_spawn"], "race":object.get("race"), "npc":object.get("npc"), "priority":object.get("priority"), "selected":object.blenderObject.select_get()} if object.get("race"): race = bge.logic.globalDict["races"][object.get("race")] if "amount-racers" not in race: race["amount-racers"] = 0 race["amount-racers"] += 1 addr = Opt.Address(objectData["position"], spawnAtDistance) if addr not in bge.logic.globalDict["spawns"]: bge.logic.globalDict["spawns"][addr] = [] bge.logic.globalDict["spawns"][addr].append(objectData) # For testing we will ignore optimization for selected ones. if objectData["selected"]: if "selected" not in bge.logic.globalDict["spawns"]: bge.logic.globalDict["spawns"]["selected"] = [] bge.logic.globalDict["spawns"]["selected"].append(objectData) print("Selected", object) object.endObject() # Crates if str(object.name).startswith("Crate"): crates = bge.logic.globalDict["garage-crates"] crates.append(object) # Spawn objects if "LightSpawn" in object: name = object["LightSpawn"] if name == "LightStand": if settings.get("poles"): spawnObject = Opt.RegisterObject(object, spawnAtDistance) spawnObject["name"] = object["LightSpawn"] spawnObject["scaling"] = [1,1,1] spawnObject["suspendDynamics"] = object.get("suspendDynamics", True) else: object.endObject() elif "Gate" in name: if settings.get("fences"): spawnObject = Opt.RegisterObject(object, spawnAtDistance) spawnObject["name"] = object["LightSpawn"] spawnObject["scaling"] = [1,1,1] spawnObject["suspendDynamics"] = object.get("suspendDynamics", True) else: object.endObject() else: spawnObject = Opt.RegisterObject(object, spawnAtDistance) spawnObject["name"] = object["LightSpawn"] spawnObject["scaling"] = [1,1,1] spawnObject["suspendDynamics"] = object.get("suspendDynamics", True) # Trees elif "Tree" in object.name: if settings.get("trees"): treeObject = Opt.RegisterObject(object, spawnAtDistance) treeObject["lods"] = { "NormalTreeTrunk": 100, #"TreeLowres": 200, # The model is ugly "TreeBillboard": 5000 } treeObject["name"] = "TreeBillboard" treeObject["scaling"] /= 1.603 else: object.endObject() elif "Palm" in object.name: if settings.get("trees"): treeObject = Opt.RegisterObject(object, spawnAtDistance) treeObject["lods"] = { "NormalPalmTrunk": 100, "PalmLow": 200, "PalmCutout": 5000 } treeObject["name"] = "PalmCutout" treeObject["scaling"] /= 1.445 else: object.endObject() # Elevators elif "Elevator" in object: elevator = {"elevator":object, "radius":object.get("Radius", 5), "levels":[], "doors":{}} for level in range(10): if "Level"+str(level) in object: elevator["levels"].append(object["Level"+str(level)]) for door in scene.objects: if door.get("ElevatorDoor") == object["Elevator"]: # Door's motion matrix doorObject = GenerateDoorObject(door) elevator["doors"][door["Level"]] = doorObject bge.logic.globalDict["elevators"][object["Elevator"]] = elevator elif "Door" in object: doorObject = GenerateDoorObject(object) if object["Door"] not in bge.logic.globalDict["doors"]: bge.logic.globalDict["doors"][object["Door"]] = {"doors":[], "radius":3} bge.logic.globalDict["doors"][object["Door"]]["doors"].append(doorObject) if "Radius" in object: bge.logic.globalDict["doors"][object["Door"]]["radius"] = object["Radius"] bge.logic.globalDict["doors"][object["Door"]]["position"] = object.position.copy() elif "ambiance-sound" in object: bge.logic.globalDict["sound-ambiances"].append(object) # Precalculating objects for smoothness preData = { "House_Shelf":4, "Moria's Bed":1, "Moria's Bed.001":1, "Sparkle": 100, "Smoke": 20, "Fire": 200, "NitroCone":5, "Road Blocker": 12 } if settings.get("trees"): preData["NormalTreeTrunk"] = 30 preData["TreeBillboard"] = 50 preData["PalmCutout"] = 32 preData["PalmLow"] = 16 preData["NormalPalmTrunk"] = 16 if settings.get("poles"): preData["LightStand"] = 50 preData["LightStand.Borked.Head"] = 5 preData["LightStand.Borked.Tail"] = 5 if settings.get("fences"): preData["MetalGate_good"] = 100 preData["GatePart"] = 100 preData["GatePart.Level0"] = 50 preData["GatePart.Level1"] = 50 print("Precalculating... ") for n, object in enumerate(preData): for i in range( preData[object] ): Reuse.Create(object, selfDestructFrames = 1, selfDestructInactive = False ) # Exiting scene def OnExit(): print("\nScene Spawn Totals:\n") for obj in Reuse.amounts: precached = preData.get(obj, 0) cached = Reuse.amounts[obj] d = cached - precached if d > 0: dc = clr["tdrd"] d = "+"+str(d) elif d <= 0: dc = clr["tdgr"] print(" "+clr["bold"]+obj+clr["norm"]+" Exited with"+clr["bold"], cached, clr["norm"]+", Started with"+clr["bold"], precached, clr["norm"]+", Difference"+dc, d , clr["norm"] ) print() Settings.SaveGame() print() scene.onRemove.append(OnExit) bge.logic.globalDict["restore-physics-timer"] = 100 bge.logic.globalDict["restore-physics"] = True # Running multiplayer daemon if settings.get("multiplayer"): multiplayer = threading.Thread(target=Multiplayer_Client.MainLoop) multiplayer.setDaemon(True) multiplayer.start() if bge.logic.globalDict["restore-physics-timer"]: bge.logic.globalDict["restore-physics-timer"] -= 2 return elif bge.logic.globalDict["restore-physics"]: bge.logic.globalDict["restore-physics"] = False dani.restorePhysics() loading.visible = False #dpos = dani.position.copy() #dpos.z += 0.5 #Destruction.AttatchFireBall(dpos, # dani, # 1) settings = bge.logic.globalDict["settings"] # Updating all the objects #if changedCamSurroundCars: Opt.ScheduleTask("Scene Chunk Updates", 0.85, Opt.UpdateScene, cam, spawnAtDistance, cam.orientation.to_euler()) # Running the story of the game Script.Run(scene, dani) # Multiplayer scene updates Multiplayer_Client.SecondaryLoop() # SPAWNING CARS spawnedCarModels = bge.logic.globalDict["spawnedCarModels"] spawnedCars = len( bge.logic.globalDict["allcars"] ) if not settings.get("multiplayer"): Opt.ScheduleTask("Car Updates", 0.80, Vehicle.SpawnLogic, camSurroundCars) Vehicle.UnspawnLogic() # ELEVATORS # Seeing on what level dani is. def atLevel(object): levelis = 0 closest = 1000 for n, i in enumerate(elevator["levels"]): dist = object.position[2] - i if dist < 0: dist *= -1 if dist < closest: closest = dist levelis = n return levelis for elevatorname in bge.logic.globalDict["elevators"]: elevator = bge.logic.globalDict["elevators"][elevatorname] # Seeing if Dani is anywhere near an elevator eloc = elevator["elevator"].position.copy() eloc[2] = dani.position[2] if dani.getDistanceTo(eloc) < elevator["radius"]: # If dani not at the same level as the elevator if atLevel(dani) != atLevel(elevator["elevator"]): toprint = "Press L to call Elevator." if toprint not in bge.logic.globalDict.get("done-prints",[]): bge.logic.globalDict["print"] = toprint # Pressing L to call it if 34 in bge.logic.globalDict["keys"]: elevator["going_to"] = atLevel(dani) elevator["closing_doors"] = True else: toprint = "Press 0-"+str(len(elevator["levels"])-1)+" activate the elevator." if toprint not in bge.logic.globalDict["done-prints"]: bge.logic.globalDict["print"] = toprint numbers = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22] for num in numbers: if num in bge.logic.globalDict["keys"] and numbers.index(num) < len(elevator["levels"]): elevator["going_to"] = numbers.index(num) elevator["closing_doors"] = True # Elevator coming if elevator.get("going_to") != None and not elevator.get("closing_doors"): destination = elevator["levels"][elevator["going_to"]] position = elevator["elevator"].position[2] if destination < position: elevator["elevator"].position[2] -= 0.1 * elevator["elevator"].get("speedFactor", 1) else: elevator["elevator"].position[2] += 0.1 * elevator["elevator"].get("speedFactor", 1) if round(destination, 1) == round(position, 1): elevator["going_to"] = None elevator["closing_doors"] = True # Doors if elevator.get("closing_doors"): cancelBucket = [] # If elevator is moving, all doors should be closed. if elevator.get("going_to") != None: openLevel = -1 else: openLevel = atLevel(elevator["elevator"]) for level in elevator["doors"]: door = elevator["doors"][level] # The elevator is at the current door's level, # the door should be open. if level == openLevel: openClose = "Open" else: openClose = "Closed" onTarget = OpenCloseDoor(door, openClose) cancelBucket.append(onTarget) if all(cancelBucket): elevator["closing_doors"] = False # DOOR ( in general ) for doorname in bge.logic.globalDict["doors"]: doors = bge.logic.globalDict["doors"][doorname] if doors.get("doOpenClose"): cancelBucket = [] for door in doors["doors"]: onTarget = OpenCloseDoor(door, doors["OpenClosed"]) cancelBucket.append(onTarget) if all(cancelBucket): doors["doOpenClose"] = False else: if doors.get("OpenClosed", "Closed") == "Closed" and dani.getDistanceTo(doors["position"]) < doors["radius"]: doors["OpenClosed"] = "Open" doors["doOpenClose"] = True elif doors.get("OpenClosed") == "Open" and dani.getDistanceTo(doors["position"]) > doors["radius"]: doors["OpenClosed"] = "Closed" doors["doOpenClose"] = True # Sound if doors.get("doOpenClose"): device = bge.logic.globalDict["SoundDevice"] for n, door in enumerate(doors["doors"]): s = "//sfx/home_door.ogg" code = str(n)+s if code not in bge.logic.globalDict["sounds"]: bge.logic.globalDict["sounds"][code] = {"sound":aud.Sound(bge.logic.expandPath(s)), "play":None} sound = bge.logic.globalDict["sounds"][code] sound["play"] = device.play(sound["sound"]) sound["play"].location = door["door"].position sound["play"].velocity = door["door"].getLinearVelocity() sound["play"].relative = False sound["play"].distance_maximum = 100 sound["play"].distance_reference = 1 sound["play"].attenuation = 1 sound["play"].pitch = random.uniform(1, 2) sound["play"].volume = 0.3 # WHEEL UP DOWN cam_parent = scene.objects["DaniCam_Parent"] wheelup = cont.sensors["wheel_up"] wheeldown = cont.sensors["wheel_down"] if wheelup.status: cam_parent.scaling /= 1.1 elif wheeldown.status and cam_parent.scaling[0] < 20: cam_parent.scaling *= 1.1 # CHEAT CODES cheat_spawn = scene.objects["Dani_Cheater"] keys = bge.logic.keyboard bge.logic.globalDict["keys"] = [] for keyn in keys.inputs: key = keys.inputs[keyn] if key.active: bge.logic.globalDict["keys"].append(keyn) keys = bge.logic.mouse bge.logic.globalDict["mouse"] = [] for keyn in keys.inputs: key = keys.inputs[keyn] if key.active: bge.logic.globalDict["mouse"].append(keyn) keys = bge.logic.globalDict["keys"] # Control release if "mouse-active" not in bge.logic.globalDict: bge.logic.globalDict["mouse-active"] = True if keycodes["Tab"] in keys and not bge.logic.globalDict.get("mouse-active-timer"): bge.logic.globalDict["mouse-active"] = not bge.logic.globalDict["mouse-active"] bge.logic.globalDict["mouse-active-timer"] = 10 if bge.logic.globalDict.get("mouse-active-timer"): bge.logic.globalDict["mouse-active-timer"] -= 1 if keys and settings.get("dev-cheats"): #print("Key pressed code:",keys.events) if "cheat" not in bge.logic.globalDict: bge.logic.globalDict["cheat"] = [0] for i in keys: if i != bge.logic.globalDict["cheat"][-1]: bge.logic.globalDict["cheat"].append(i) # SPAWN CHEATS cheats = { "NeonSpeedsterBox": "NEONSPEDSTER", "RedKissBox": "REDKIS", "DarkShadowBox": "DARKSHADOW", "TruckBox": "THETRUCK", "HatchBack01Box": "HATCHBACK1", "KartBox": "KARTCAR", } for i in cheats: code = bge.logic.globalDict["cheat"][-(len(cheats[i])):] numericalcode = [] for letter in cheats[i]: numericalcode.append(keycodes[letter]) if code == numericalcode: print("Spawning:", i) car = Vehicle.Spawn(i, cheat_spawn.position, cheat_spawn.orientation, color="pallete") bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["print"] = "A Vehicle Is Waiting For You, Sir." bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding teleportations = [ #[[-75.19, 1028, 0], "RACETRACK"], [[-68.35, 946.6, 4.738], "RACETRACK"], [[-752.78, -937.4, 411.08], "HOUSE"], [[-755.1, -1041, 405.8], "GARAGE"], [[-792.10,-980.60, 405.50], "PARKING"], [[-937.3, -277.1, 257.7], "MANSION"], [[-254.4, -508.1, 189.2], "BIGBUILDING"], [[232.9, -120.4, 42.22], "NEARSEA"], [[229.9, -811.9, 175.3], "PITOSTATUE"], [[659.4, -616.1,202.9], "CONSTRUCTION"], [[8.5, -45.28, 2.65], "KARTING"], [[-2.122, 1322, 99.85], "TOWER0"], [[-172.4, 1147, 99.68], "TOWER1"], [[200, 1204, 100], "TOWER2"], [[12.19, 1127, 139.3], "TOWER3"], [[148.4, 941.7, 98.83], "TOWER4"], [[-725, -984.6, 409.2], "CINEMA"] ] for i in teleportations: code = bge.logic.globalDict["cheat"][-(len(i[1])):] numericalcode = [] for letter in i[1]: numericalcode.append(keycodes[letter]) if code == numericalcode: if not dani.get("driving"): Character_Controll.ChangeCameraTarget(dani.children["Dani_cam_Target"], 100, [1,1,1]) dani.position = i[0] else: dani["driving"].position = i[0] dani["driving"].position.z += 2 bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["print"] = "Teleportation Finished, Sir." bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # Money code code = bge.logic.globalDict["cheat"][-(len("givememoney")):] if code == [29, 31, 44, 27, 35, 27, 35, 37, 36, 27, 47]: Money.Recieve(569) bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["print"] = "Enjoy The Money, Sir." code = bge.logic.globalDict["cheat"][-(len("givemez")):] if code == [29, 31, 44, 27, 35, 27, 48]: bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["print"] = "Enjoy The Nitro, Sir." Vehicle.AddNitroCan(dani["driving"]) dani["driving"]["nitro"] = 10.0 # Puruit code code = bge.logic.globalDict["cheat"][-(len("pursuit")):] if code == [38, 43, 40, 41, 43, 31, 42]: bge.logic.globalDict["pursuit-cheat"] = not bge.logic.globalDict["pursuit-cheat"] bge.logic.globalDict["cheat"] = [0] if bge.logic.globalDict["pursuit-cheat"]: bge.logic.globalDict["print"] = "Everybody Hates You, Sir. At Your Request, Sir." else: bge.logic.globalDict["print"] = "Everybody Stopped Hating You, Sir." bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # Derby code code = bge.logic.globalDict["cheat"][-(len("derby")):] if code == [26, 27, 40, 24, 47]: bge.logic.globalDict["derby-cheat"] = not bge.logic.globalDict["derby-cheat"] bge.logic.globalDict["cheat"] = [0] if bge.logic.globalDict["derby-cheat"]: bge.logic.globalDict["print"] = "Everybody Is Crazy, Sir." else: bge.logic.globalDict["print"] = "Everybody Stopped Being Crazy, Sir." bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # Gravity code code = bge.logic.globalDict["cheat"][-(len("gravity")):] if code == [29, 40, 23, 44, 31, 42, 47]: bge.logic.globalDict["gravity"] = not bge.logic.globalDict["gravity"] if bge.logic.globalDict["gravity"]: bge.constraints.setGravity(0, 0, -9.8) else: bge.constraints.setGravity(0, 0, 0) bge.logic.globalDict["cheat"] = [0] if bge.logic.globalDict["gravity"]: bge.logic.globalDict["print"] = "We're Back To Earth, Sir." else: bge.logic.globalDict["print"] = "We're Up In Space, Sir." bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # Explosion code code = bge.logic.globalDict["cheat"][-(len("bom")):] if code == [24,37,35]: expos = cheat_spawn.position.copy() expos[2] = dani.position[2] Destruction.Explosion(expos, mass=10, size=10) bge.logic.globalDict["print"] = "Boom! , Sir." bge.logic.globalDict["cheat"] = [0] # no ding here, the boom is enough # Fix car code: code = bge.logic.globalDict["cheat"][-(len("fixcar")):] if code == [28, 31, 46, 25, 23, 40]: car = dani.get("driving") Vehicle.Fix(car) bge.logic.globalDict["print"] = "The Car is like New, Sir." bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # Color Car code: code = bge.logic.globalDict["cheat"][-(len("colorcar")):] if code == [25, 37, 34, 37, 40, 25, 23, 40]: car = dani.get("driving") Vehicle.SmartColor(car, color="pallete") bge.logic.globalDict["print"] = "The Car is colored, Sir." bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # Color Car code: code = bge.logic.globalDict["cheat"][-(len("carnpc")):] if code == [25, 23, 40, 36, 38, 25]: car = dani.get("driving") car["target"] = [] car["npc"] = "npc" car["active"] = False bge.logic.globalDict["print"] = "The Car is NPC, Sir." bge.logic.globalDict["cheat"] = [0] bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding # RACES for racename in bge.logic.globalDict["races"]: race = bge.logic.globalDict["races"][racename] pointer = scene.objects["PointingArrow"] posindicator = scene.objects["Dani_Pos_Indicator"] timeindicator = scene.objects["Dani_Time_Indicator"] lapindicator = scene.objects["Dani_Lap_Indicator"] reward = race.get("reward", 1000) bid = reward / (race.get("amount-racers", 1)+1) intime = Racing.intime(race) after = race.get("after") during = race.get("during") duringcheck = dani.get("race") == after and Script.Story.get(during) aftercheck = duringcheck or after in Script.Story["passed"] or not after # Show them on the map if ( not dani.get("race") and aftercheck and Money.Have(bid)) or duringcheck: Map.Show(race["starters"][0]["location"], icon="Map_Circle", color=[0.01,0.01,1], ID=racename) if not race["started"] and ( ( not dani.get("race") and Money.Have(bid) ) or duringcheck ) and race["racers"] and aftercheck: for starter in race["starters"]: if not starter["cylinder"] and dani.getDistanceTo(starter["location"]) < spawnAtDistance: starter["cylinder"] = Reuse.Create("Starter.Cylinder") starter["cylinder"].position = starter["location"] starter["cylinder"].orientation = starter["rotation"] starter["cylinder"].scaling[0] = starter["radius"] starter["cylinder"].scaling[1] = starter["radius"] if dani.getDistanceTo(starter["location"]) < starter["radius"]: NPC_type_cars = bge.logic.globalDict.get("NPC_type_cars", {}) cartype = race.get("type") if dani["driving"] and dani["driving"].name in NPC_type_cars.get(cartype,[]): if not intime: bge.logic.globalDict["print"] = "Come here "+Racing.renderTimeRange(race) continue if not duringcheck: bge.logic.globalDict["print"] = "Press R to start the race.\nEverybody bids $"+str(int(bid))+"\nWinner gets $"+str(int(race.get("reward"))) else: bge.logic.globalDict["print"] = "Press R to start the race." if keycodes["R"] in keys: if not duringcheck: Money.Pay(bid) race["started"] = True Reuse.Delete(starter["cylinder"]) starter["cylinder"] = None race["start-time"] = bge.logic.getRealTime() for racer in race["racers"]: racer["racing"] = True racer["launchtime"] = 100 racer["race"] = racename # Testing racer["npc"] = "racer" racer["active"] = False # Beam of energy racer["beam"] = scene.addObject("Racer.Indicator", "Racer.Indicator") dani["race"] = racename dani["checkpoint"] = 0 dani["lap"] = 0 posindicator.visible = True pointer.visible = True timeindicator.visible = True lapindicator.visible = True bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["active"]["sound"]) # Play a Ding else: bge.logic.globalDict["print"] = "Come here with a "+cartype+" to race." # If this race is going elif dani.get("race") == racename: nextcheck = race["checkpoints"][dani["checkpoint"]] nextcheckpoint = race["checkpoints"][ ( dani.get("checkpoint") + 1 ) % len(race["checkpoints"]) ] # Alight the arrow to the checkpoint tocheck = pointer.getVectTo(nextcheck["location"]) pointer.alignAxisToVect(tocheck[1], 1, 0.1) # Alighn the arrow to the next checkpoint if close enough to it. if cam.pointInsideFrustum(nextcheck["location"]) == cam.INSIDE: tonextcheck = pointer.getVectTo(nextcheckpoint["location"]) pointer.alignAxisToVect(tonextcheck[1], 1, min(1, max(0, 1-(tocheck[0]/500))) ** 5 ) # Align the arrow vertically pointer.alignAxisToVect( (0,0,1), 2, 1.0 ) # Time of the race currentRaceTime = bge.logic.getRealTime() - race["start-time"] formattedTime = str(datetime.timedelta(seconds=currentRaceTime))[:-4] while formattedTime.startswith("0") or formattedTime.startswith(":"): formattedTime = formattedTime[1:] if formattedTime.startswith("."): formattedTime = "0"+formattedTime timeindicator["Text"] = formattedTime lapindicator["Text"] = str(dani["lap"]+1)+"/"+str(race["laps"]) if not nextcheck["cylinder"] and dani.getDistanceTo(nextcheck["location"]) < spawnAtDistance: nextcheck["cylinder"] = Reuse.Create("Tag.Cylinder") nextcheck["cylinder"].position = nextcheck["location"] nextcheck["cylinder"].orientation = nextcheck["rotation"] nextcheck["cylinder"].scaling[0] = nextcheck["radius"] * 0.8 nextcheck["cylinder"].scaling[1] = nextcheck["radius"] * 0.8 Map.Show(nextcheck["location"], icon="Map_Circle", color=[1,0.3,0], ID="RaceCheckpoint") Map.Show(nextcheckpoint["location"], icon="Map_Circle", color=[1,0.1,0], ID="RaceCheckpoint2") if dani.getDistanceTo(nextcheck["location"]) < nextcheck["radius"]*1.5: if not nextcheck.get("OnLoop"): dani["prevrescue"] = dani.get("rescue") dani["rescue"] = nextcheck["location"] dani["rescueTo"] = dani["checkpoint"] Reuse.Delete(nextcheck["cylinder"]) nextcheck["cylinder"] = None # Logging speed for better AI #if "raceData" not in race: nextcheck["speed"] = -dani["driving"].localLinearVelocity[1] nextcheck["time"] = currentRaceTime nextcheck["rot"] = list(dani["driving"].orientation.to_euler()) #if race["positions"].index(dani) == 0: # race["raceData"]["speed"][dani["checkpoint"]] = -dani["driving"].localLinearVelocity[1] # race["raceData"]["time"][dani["checkpoint"]] = currentRaceTime # race["raceData"]["rotz"][dani["checkpoint"]] = dani["driving"].orientation.to_euler()[2] dani["checkpoint"] += 1 bge.logic.globalDict["SoundDevice"].play(bge.logic.globalDict["sounds"]["checkpoint"]["sound"]) # Play a Ding if dani["checkpoint"] == len(race["checkpoints"]): dani["checkpoint"] = 0 dani["lap"] += 1 print('"'+racename+'" : {') print('"speed": [') for c in race["checkpoints"]: print(c.get("speed"),",") print('],\n"time":[') for c in race["checkpoints"]: print(c.get("time"),",") print('],\n"rot":[') for c in race["checkpoints"]: print(c.get("rot"),",") print(']},') # If finished race if dani["lap"] == race["laps"]:# or not dani["driving"]: dani["race"] = None race["started"] = False posindicator.visible = False timeindicator.visible = False pointer.visible = False lapindicator.visible = False race["racer_spawns"] = [] for racer in race["racers"]: racer["npc"] = "npc" racer["beam"].endObject() race["racers"] = [] if nextcheck["cylinder"]: Reuse.Delete(nextcheck["cylinder"]) nextcheck["cylinder"] = None # If won if race["positions"].index(dani) == 0: bge.logic.globalDict["print"] = "You've Won This Race!\nTime: "+formattedTime+"\nReward: $"+str(int(race.get("reward", 0))) Money.Recieve(race.get("reward", 0)) # If finished else: bge.logic.globalDict["print"] = "You finished number "+str(race["positions"].index(dani)+1) + " Time: "+formattedTime Script.StatusText(" ") continue positions = [] for racer in race["racers"]: racer["into_race"] = [race["laps"] - racer["lap"], len(race["checkpoints"]) - racer["checkpoint"], racer.getDistanceTo(race["checkpoints"][racer["checkpoint"]]["location"])] positions.append([racer["into_race"], racer]) dani["into_race"] = [race["laps"] - dani["lap"], len(race["checkpoints"]) - dani["checkpoint"], dani.getDistanceTo(race["checkpoints"][dani["checkpoint"]]["location"])] positions.append([dani["into_race"], dani]) positions = sorted(positions) race["positions"] = [] for position, racer in positions: race["positions"].append(racer) posindicator["Text"] = str(race["positions"].index(dani)+1) # The positions text ( with Dani's car being Bold and yellow ) pt = "" bold = [] for n, p in enumerate(race["positions"]): n += 1 if p == dani: try: t = dani.get("driving", "On Foot")["specs"]["name"]+" | "+str(n)+"\n" except: t = str(dani.get("driving", "On Foot"))+" | "+str(n)+"\n" bold = range(len(pt), len(pt)+len(t)) else: try: t = p["specs"]["name"]+" | "+str(n)+"\n" except: t = str(p)+" | "+str(n)+"\n" pt = pt + t Script.StatusText(pt, bold) # Messages if "done-prints" not in bge.logic.globalDict: bge.logic.globalDict["done-prints"] = [] if bge.logic.globalDict.get("print") and bge.logic.globalDict.get("last_print") != bge.logic.globalDict["print"]: print() for line in bge.logic.globalDict["print"].split("\n"): print(" "+clr["bold"]+clr["tdyl"]+line+clr["norm"]) print() #scene.objects["Messages"]["Text"] = str(bge.logic.globalDict.get("print")) scene.objects["Messages"].blenderObject.data.body = str(bge.logic.globalDict.get("print")) scene.objects["Messages"].stopAction() scene.objects["Messages"].playAction("MessagesAction", 0, 100) bge.logic.globalDict["print-change-size"] = True bge.logic.globalDict["last_print"] = bge.logic.globalDict["print"] if bge.logic.globalDict["print"] not in bge.logic.globalDict["done-prints"]: bge.logic.globalDict["done-prints"].append(bge.logic.globalDict["print"]) bge.logic.globalDict["print"] = "" elif bge.logic.globalDict.get("print-change-size"): # Changing the size of the element under the text # This is done in a different frame, because we need # to let it update the depsgraph with the text dimensions. camscale = scene.objects["DaniCam_Parent"].scaling[0] textSize = scene.objects["Messages"].blenderObject.dimensions thingSize = scene.objects["Message_Background"].blenderObject.dimensions thingScale = scene.objects["Message_Background"].worldScale textSize = mathutils.Vector(( textSize.x + ( 0.04 * camscale ), textSize.y + ( 0.02 * camscale ), textSize.z )) thingSize = mathutils.Vector(( thingSize.x / thingScale.x, thingSize.y / thingScale.y, thingSize.z / thingScale.z )) thingScale = mathutils.Vector(( textSize.x / thingSize.x, textSize.y / thingSize.y, 1.0 # It doesn't matter, and making it 0 collapes the object )) scene.objects["Message_Background"].worldScale = thingScale point = Vehicle.RelativePoint(scene.objects["Messages"], (-0.007 * camscale, (-0.010 * camscale) + (textSize.y / 2), -0.001)) scene.objects["Message_Background"].worldPosition = point bge.logic.globalDict["print-change-size"] = False # SOUND #print(dir(aud)) if "SoundDevice" not in bge.logic.globalDict: bge.logic.globalDict["SoundDevice"] = aud.Device() bge.logic.globalDict["SoundDevice"].distance_model = aud.DISTANCE_MODEL_INVERSE_CLAMPED bge.logic.globalDict["sounds"] = {} bge.logic.globalDict["sounds"]["active"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/active.ogg")), "play":None} # Angry pursuit sounds bge.logic.globalDict["sounds_angry_start"] = [] for i in range(8): i += 1 i = str(i) if len(i) < 2: i = "0"+i i = "//sfx/voices/angry_pursuit/start_"+i+".ogg" bge.logic.globalDict["sounds"][i] = {"sound":aud.Sound(bge.logic.expandPath(i)), "play":None} bge.logic.globalDict["sounds_angry_start"].append(i) bge.logic.globalDict["sounds_angry_hit"] = [] for i in range(5): i += 1 i = str(i) if len(i) < 2: i = "0"+i i = "//sfx/voices/angry_pursuit/hit_"+i+".ogg" bge.logic.globalDict["sounds"][i] = {"sound":aud.Sound(bge.logic.expandPath(i)), "play":None} bge.logic.globalDict["sounds_angry_hit"].append(i) # Dani voices bge.logic.globalDict["sounds"]["dani_yelling"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/yelling.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_entering"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/entering.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_ohno"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/ohno.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_ohnoindeed"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/ohnoindeed.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_wearesinking"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/wearesinking.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_ohgod"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/ohgod.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_jump"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/jump.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_land"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/land.ogg")), "play":None} bge.logic.globalDict["sounds"]["dani_walk"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/voices/dani/walk.ogg")), "play":None} # Jack voices bge.logic.globalDict["JackBoxVoices"] = {"crash":[], "near" :[], "speed":[]} JV = bge.logic.globalDict["JackBoxVoices"] JF = bge.logic.expandPath("//sfx/voices/jack/") for t in ["crash", "near", "speed"]: for f in os.listdir(JF): if f.startswith(t) and f.endswith(".ogg"): name = f.replace(".ogg", "") bge.logic.globalDict["sounds"]["jack_"+name] = {"sound":aud.Sound(JF+f), "play":None} JV[t].append(bge.logic.globalDict["sounds"]["jack_"+name]) # Car Sounds bge.logic.globalDict["sounds"]["door"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/door.ogg")), "play":None} bge.logic.globalDict["sounds"]["tire_pop"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/tire_pop.ogg")), "play":None} # Race sounds bge.logic.globalDict["sounds"]["checkpoint"] = {"sound":aud.Sound(bge.logic.expandPath("//sfx/checkpoint.ogg")), "play":None} device = bge.logic.globalDict["SoundDevice"] device.listener_location = scene.active_camera.worldPosition device.listener_orientation = scene.active_camera.worldOrientation.to_quaternion() device.listener_velocity = scene.active_camera.getLinearVelocity() for i in bge.logic.globalDict["sound-ambiances"]: s = i["ambiance-sound"] #s = "//sfx/ambiance/forest.ogg" if s not in bge.logic.globalDict["sounds"]: bge.logic.globalDict["sounds"][s] = {"sound":aud.Sound(bge.logic.expandPath(s)), "play":None} sound = bge.logic.globalDict["sounds"][s] if not sound["play"] or not sound["play"].status: sound["play"] = device.play(sound["sound"]) scale = i.scaling[0] distance = i.getDistanceTo(dani) if inCinema: sound["inCinema"] = sound.get("inCinema", 1) * 0.95 elif sound.get("inCinema", 1) < 1: if sound["inCinema"] < 0.1: sound["inCinema"] = 0.1 sound["inCinema"] = sound.get("inCinema", 1) * 1.05 sound["play"].volume = max(0, min(1, (1-(distance / scale ))*5))*i.get("volume", 1) * sound.get("inCinema", 1) ########## LODS FOR CHUNKS OF THE ROAD ############# if "LODchunks" not in bge.logic.globalDict: bge.logic.globalDict["LODchunks"] = {"TheRacetrack":{ "object":scene.objects["TheRacetrack"], "high":"TheRacetrackHigh", "radius":1000, "now":"high", "name":"Papses Racetrack" }, "TheCity":{ "object":scene.objects["TheCity"], "high":"TheCityHigh", "radius":1500, "now":"high", "name":"Dune Town" }, "TheHouse":{ "object":scene.objects["TheHouse"], "high":"TheHouseGood", "low":"TheHouseBorked", "parent":"TheCity", "radius":200, "now":"high", "name":"Looparound 8\nDani's Home" }, "HallwayPictures":{ "object":scene.objects["HallwayPictures"], "high":"HallwayPictures", "parent":"TheHouse", "radius":180, "now":"high" }, "Computer":{ "object":scene.objects["Computer"], "high":"Computer", "parent":"TheHouse", "radius":180, "now":"high" }, "Just3000Wreck":{ "object":scene.objects["Just3000Wreck"], "high":"Just3000Wreck", "parent":"TheHouse", "radius":180, "now":"high" }, "KartingTrack":{ "object":scene.objects["KartingTrack"], "high":"KartingTrack_High", "low":"KartingTrack_Low", "parent":"TheCity", "radius":200, "now":"high", "name":"Karting Track" }, "Karting_Decorations":{ "object":scene.objects["Karting_Decorations"], "high":"Karting_Decorations", "parent":"KartingTrack", "radius":180, "now":"high" }, "KartingGamesCollider":{ "object":scene.objects["KartingGamesCollider"], "high":"KartingGamesCollider", "parent":"KartingTrack", "radius":180, "now":"high" }, "KartingGamesObject":{ "object":scene.objects["KartingGamesObject"], "high":"KartingGamesObject", "parent":"KartingTrack", "radius":180, "now":"high" }, } chunks = bge.logic.globalDict["LODchunks"] for chunkname in chunks: chunk = chunks[chunkname] # Making low when out of bounds forcehide = False if chunks.get(chunk.get("parent", ""), {}).get("now") == "low": forcehide = True if chunk["object"].visible: chunk["now"] = "high" if chunk["now"] == "low" and dani.getDistanceTo(chunk["object"]) < chunk["radius"]: print(consoleForm(chunk["object"]), "is now highres.") if "low" in chunk: chunk["object"].replaceMesh(chunk["high"]) chunk["object"].visible = True chunk["object"].restorePhysics() chunk["now"] = "high" if "name" in chunk: bge.logic.globalDict["print"] = chunk["name"] elif chunk["now"] == "high" and ( dani.getDistanceTo(chunk["object"]) > chunk["radius"] or forcehide): print(consoleForm(chunk["object"]), "is now lowres.") if "low" in chunk and not forcehide: print("making mesh low") chunk["object"].replaceMesh(chunk["low"]) else: print("hiding mesh") chunk["object"].visible = False if not dani.get("race"): chunk["object"].suspendPhysics() chunk["now"] = "low" ############ Camera UI ########### Map.UpdateMapUI() #Map.Show([0,0,0], icon="Map_Circle") ############ GARAGE ########## # The idea is that all cars inside of the garage will # stay in the garage. garage = scene.objects["GarageColider"] garageDistance = 70 if dani.getDistanceTo(garage) > garageDistance: Garage.Encode() elif dani.getDistanceTo(garage) < garageDistance - 10: Garage.Decode() # Crates # There are crates in the house, in the garage. They are rigid body objects. # the problem is that when you go far enough away, the ground beneath them # stops being solid, so we need to deactiave their physics. crates = bge.logic.globalDict["garage-crates"] for crate in crates: if dani.getDistanceTo(crate) > 100: crate.suspendPhysics() elif dani.getDistanceTo(crate) < 90: crate.restorePhysics() # Tools Tools.MainLoop() Garage.Computer() ################ DAY NIGHT CYCLE ################ clock = scene.objects["Dani_Clock_Indicator"] bge.logic.globalDict["time"] = bge.logic.globalDict["start-time"] + ( bge.logic.getRealTime() / 3600 * settings.get("clockspeed", 20) ) while bge.logic.globalDict["time"] > 24: bge.logic.globalDict["time"] -= 24 timeis = bge.logic.globalDict["time"] # Printing the clock hrtext = str(int(timeis)) if len(hrtext) < 2: hrtext = "0" +hrtext mntext = str(int((timeis-int(timeis))*60)) if len(mntext) < 2: mntext = "0" + mntext clock["Text"] = hrtext+":"+mntext # Getting the time outthere timefactor = timeis / 24 # we want 100 sunlight to be at 12 AM not at 24 hours #timefactor -= 0.5 #if timefactor < 0: timefactor *= -1 #timefactor *= -2 #timefactor += 1 timecontroller = scene.objects["TimeController"] timecontroller.position.x = ( timefactor * 100 ) - 100 # Sun rotation sun = scene.objects["Sun"] sunrot = sun.worldOrientation.to_euler() sunrot.y = ( -timefactor * math.pi * 2 ) + math.pi sun.worldOrientation = sunrot # trying to limit the next operations a bit if not bge.logic.globalDict.get("time-update-timer"): TheCity = scene.objects["TheCity"] TheCity.blenderObject["time"] = timefactor TheCity.applyRotation((0,0,0)) TheRacetrack = scene.objects["TheRacetrack"] TheRacetrack.blenderObject["time"] = timefactor TheRacetrack.applyRotation((0,0,0)) Water = scene.objects["Water"] Water.blenderObject["time"] = timefactor Water.applyRotation((0,0,0)) # we want 100 sunlight to be at 12 AM not at 24 hours timefactor -= 0.5 if timefactor < 0: timefactor *= -1 timefactor *= -2 timefactor += 1 sun.blenderObject.data.energy = 3 * timefactor bge.logic.globalDict["time-update-timer"] = 500 else: bge.logic.globalDict["time-update-timer"] -= 1 # Background racetrack / city backdrop calcualtion city_at = 137 racetrack_at = 630 now_at = float(cam.worldPosition.y) if now_at > racetrack_at: crFactor = 1.0 elif now_at < city_at: crFactor = 0.0 else: crFactor = (now_at - city_at) / ( racetrack_at - city_at ) timecontroller.position.y = ( crFactor * 100 ) - 100 # Moving the background up and down depending on the position of # the camera. max_z = 39 min_z = -12 now_z = float(cam.worldPosition.z) move_z = 14 if now_z > max_z: mzFactor = 0.0 elif now_z < min_z: mzFactor = 1.0 else: mzFactor = 1- ((now_z - min_z) / ( max_z - min_z )) timecontroller.position.z = ( mzFactor * move_z ) # Now to position the racetrack properly we want to rotate it p1 = [7.39, -805.686] p2 = [30 , 95.5932] cur_x = float(cam.worldPosition.x) rotFactor = (cur_x - p1[1]) / (p2[1] - p1[1]) * ( p2[0] - p1[0] ) + p1[0] rotationcontroller = scene.objects["Racetrack_rotaion"] rotationcontroller.position.x = rotFactor # Now the same object at Z will control the level of the volumetric # Water effect. ( Important when below water level, but not in the # water ). waterleveler = scene.objects["WaterLevel"] if dani.position.y < 0: waterleveler.position.z = -1000 else: waterleveler.position.z = 0