import bge import bpy import aud import time import datetime import threading import random import numpy import math import mathutils import Reuse import Distraction import Opt # SPAWNING ASSETS AND STUFF spawnAtDistance = 300 maxCars = 6 scene = bge.logic.getCurrentScene() cont = bge.logic.getCurrentController() dani = scene.objects["Dani_Box"] cam = scene.active_camera FPS = bge.logic.getAverageFrameRate() goodFPS = FPS >= 30 camSurround = Opt.Surround(cam.position, spawnAtDistance/2)#, cam.orientation.to_euler()) camSurroundCars = Opt.Surround(cam.position, spawnAtDistance)#, cam.orientation.to_euler()) inCinema = scene.objects["CinemaColider"]["InCinema"] #print(bge.logic.globalDict.get("reuse")) # Destroy those needing destroying Reuse.SelfDestructDo() # Dani water boyancy if dani["underwater"] and dani.position[2] < -9.5 and not dani["driving"]: dani.applyForce([0,0,min(0.6, -0.5*(dani.position[2]+9.5))]) scene.objects["DanisRig"]["underwater"] = True elif dani.position[2] > -9.5: dani["underwater"] = False scene.objects["DanisRig"]["underwater"] = False # 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["NPC_cars"] = NPC_cars 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 = [] for n, axis in enumerate(["X", "Y", "Z"]): 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 "spawns" not in bge.logic.globalDict: bge.logic.globalDict["spawns"] = {} # Spawn points for cars bge.logic.globalDict["light-spawns"] = {} # Spawn points for destructables ( such as lights ) bge.logic.globalDict["allcars"] = [] # List of all spawned cars bge.logic.globalDict["spawnedCarModels"] = [] # List of models of cars that were spawned already. bge.logic.globalDict["all-lights"] = [] # List with all spawned lights bge.logic.globalDict["sound-ambiances"] = [] # Points generating ambiant sounds bge.logic.globalDict["elevators"] = {} # Handles Elevators bge.logic.globalDict["doors"] = {} # Handles Doors bge.logic.globalDict["trees"] = {"spawned":[], "cu":1000 } # Handles Trees # Adding spawn points to the lists for i in scene.objects: if "spawn" in i: lightSpawns = bge.logic.globalDict["light-spawns"] objectData = {"position": i.worldPosition.copy(), "orientation": i.worldOrientation.copy(), "spawn": i.get("spawn"), "to_spawn": i["to_spawn"], "race":i.get("race"), "npc":i.get("npc")} 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) i.endObject() elif "Elevator" in i: elevator = {"elevator":i, "radius":i.get("Radius", 5), "levels":[], "doors":{}} for level in range(10): if "Level"+str(level) in i: elevator["levels"].append(i["Level"+str(level)]) for door in scene.objects: if door.get("ElevatorDoor") == i["Elevator"]: # Door's motion matrix doorObject = GenerateDoorObject(door) elevator["doors"][door["Level"]] = doorObject bge.logic.globalDict["elevators"][i["Elevator"]] = elevator elif "Door" in i: doorObject = GenerateDoorObject(i) if i["Door"] not in bge.logic.globalDict["doors"]: bge.logic.globalDict["doors"][i["Door"]] = {"doors":[], "radius":3} bge.logic.globalDict["doors"][i["Door"]]["doors"].append(doorObject) if "Radius" in i: bge.logic.globalDict["doors"][i["Door"]]["radius"] = i["Radius"] bge.logic.globalDict["doors"][i["Door"]]["position"] = i.position.copy() elif "LightSpawn" in i: lightSpawns = bge.logic.globalDict["light-spawns"] objectData = {"position": i.worldPosition.copy(), "orientation": i.worldOrientation.copy(), "movez": i.get("movez", 0), "to_spawn": i["to_spawn"], "broken":False, "spawned_object": i.get("spawned_object"), "good": i.get("good"), "LightSpawn": i["LightSpawn"]} addr = Opt.Address(objectData["position"], spawnAtDistance/2) if addr not in lightSpawns: lightSpawns[addr] = [] lightSpawns[addr].append(objectData) i.endObject() elif "ambiance-sound" in i: bge.logic.globalDict["sound-ambiances"].append(i) ######## TREES ####### elif "Tree" in i.name: tree_object = {"position":i.position.copy(), "orientation":i.orientation.copy(), "scaling":i.scaling.copy(), "tree":"NormalTreeTrunk", "treelow":"TreeLowres", "treeverylow":"TreeBillboard", "to_spawn":True} i.endObject() addr = Opt.Address(tree_object["position"], spawnAtDistance) if addr not in bge.logic.globalDict["trees"]: bge.logic.globalDict["trees"][addr] = [] bge.logic.globalDict["trees"][addr].append(tree_object) # Cheat code modes bge.logic.globalDict["pursuit-cheat"] = False bge.logic.globalDict["derby-cheat"] = False bge.logic.globalDict["gravity"] = True # Making races bge.logic.globalDict["races"] = {} # Object containing infor about races # Yes i'm using BPY, shut up! for collection in bpy.data.collections['Races'].children: race = {"starters":[], "checkpoints":[], "racers":[], "racer_spawns": [], "started":False } for object in collection.objects: tag = {"location":object.location, "rotation":object.rotation_euler, "radius":object.scale[0], "OnLoop":object.get("OnLoop"), "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 checkpoints ( the yellow cylinder ) else: race["checkpoints"].append(tag) bge.logic.globalDict["races"][collection.name] = race # Precalculating objects for smoothness preData = {"MetalGate_good":50, "GatePart":50, "LightStand": 20, "NormalTreeTrunk":20, #"TreeLowres":8, "TreeBillboard":30, "House_Shelf":4, "Moria's Bed":1, "Moria's Bed.001":1, "Sparkle": 100, "Smoke": 20, "LightStand.Borked.Head": 5, "LightStand.Borked.Tail": 5, "GatePart.Level0": 50, "GatePart.Level1": 50, "Fire": 200, "Road Blocker": 12 } print("Precalculating... ") for n, object in enumerate(preData): for i in range( preData[object] ): Reuse.Create(object, selfDestructFrames = 1, selfDestructInactive = False ) # This is a good idea in theory ( so I'm keeping this code ). But... # For some reason cars become way faster when I do this. Weird. # for carModel in NPC_cars: # # car = Reuse.Create(carModel, selfDestructFrames = 1 ) # car["underwater"] = False # rig = car.children[car.get("rig","RIG")] # body = rig.children["Car_body"] # body["good"] = body.meshes[0].name # bge.logic.globalDict["spawnedCarModels"].append(carModel) # SPAWNING CARS spawnedCarModels = bge.logic.globalDict["spawnedCarModels"] spawnedCars = len( bge.logic.globalDict["allcars"] ) SpawnsCloseEnough = [] for i in camSurroundCars: SpawnsCloseEnough += bge.logic.globalDict["spawns"].get(i, []) for spawnPoint in SpawnsCloseEnough: inview = cam.pointInsideFrustum(spawnPoint["position"]) == cam.INSIDE distance = cam.getDistanceTo(spawnPoint["position"]) # Car information carModel = spawnPoint["spawn"] carBehaviour = spawnPoint.get("npc") carRace = spawnPoint.get("race") # If this is a road npc, we want to choose a random car model if carBehaviour == "npc": carModel = numpy.random.choice(NPC_cars, p=NPC_cars_probability) toSpawn = spawnPoint["to_spawn"] and inview and spawnAtDistance / 2 < distance < spawnAtDistance and spawnedCars < maxCars else: toSpawn = spawnPoint["to_spawn"] and inview and distance < spawnAtDistance # Trying not to add any more cars than nessesary if toSpawn and carModel in Reuse.amounts and not Reuse.reuse.get(carModel): force_add = False # Making sure that the race still works if carRace and not dani.get("race"): for car in bge.logic.globalDict["allcars"]: if car.name == carModel: if not car.get("active"): Reuse.Delete(car, inactive=True) else: force_add = True break if carRace: force_add = True if not force_add: continue # Spawning a car if goodFPS and toSpawn: # Making car car, new = Reuse.Create(carModel, declarenew=True) # If you claimed the car, one more car! if car["active"]: car, new = Reuse.Create(carModel, declarenew=True) car.position = spawnPoint["position"] car.orientation = spawnPoint["orientation"] if carBehaviour == "npc": car.setLinearVelocity([0,-15,0], True) else: car["spawnPoint"] = spawnPoint car["npc"] = carBehaviour car["enemy"] = "" car["chased"] = False car["launchtime"] = 300 if carRace: car["race"] = carRace car["racing"] = False car["checkpoint"] = 0 car["rescue"] = bge.logic.globalDict["races"][carRace]["starters"][0]["location"] car["lap"] = 0 car["blown"] = False bge.logic.globalDict["races"][carRace]["racers"].append(car) bge.logic.globalDict["races"][carRace]["racer_spawns"].append(spawnPoint) # Cars are deformable during game, so we will need to restore them rig = car.children[car.get("rig","RIG")] body = rig.children["Car_body"] # Doors ( some cars have them falling ) try: rig.children["Door_Pease.001"].visible = True rig.children["Door_Pease"].visible = True except: pass # If it's a fresh car if new: body["good"] = body.meshes[0].name # Making sure not to spawn too many cars. spawnedCarModels.append(carModel) else: # Restoring car body.replaceMesh( body["good"] ) vehicle = bge.constraints.getVehicleConstraint(car["cid"]) # Restoring wheels for i in range(4): vehicle.setSuspensionStiffness(car.get("suspension", 200), i) vehicle.setTyreFriction(car.get("friction", 1), i) vehicle.setRollInfluence(car.get("roll", 0), i) bge.logic.globalDict[car["cid"]]["wheels"][i].setVisible(True) for i in ["Front_Right", "Front_Left", "Back_Left", "Back_Right"]: car[i] = 1 bge.logic.globalDict["allcars"].append(car) spawnPoint["to_spawn"] = False spawnPoint["to_spawn_timer"] = 1000 break # If player is standing still keep spawning cars near by if not spawnPoint["to_spawn"] and spawnPoint["to_spawn_timer"]: spawnPoint["to_spawn_timer"] -= 1 elif not spawnPoint["to_spawn"] and carBehaviour == "npc": spawnPoint["to_spawn"] = True # LIGHTS AND OTHER DISTRACTABLES # Getting all the spawns within a certain distance SpawnsCloseEnough = [] for i in camSurround: SpawnsCloseEnough += bge.logic.globalDict["light-spawns"].get(i, []) # Sorting them by distance byDistance = [] for n, i in enumerate(SpawnsCloseEnough): distance = cam.getDistanceTo(i["position"]) byDistance.append([distance, n, i]) byDistance = sorted(byDistance) # Spawning the objects for i in byDistance: distance, n, i = i inmemory = Reuse.reuse.get(i["LightSpawn"]) inview = cam.pointInsideFrustum(i["position"]) == cam.INSIDE if goodFPS and inview and inmemory and i["to_spawn"] and not i["broken"]: obj = Reuse.Create(i["LightSpawn"]) obj.suspendDynamics(True) obj.position = i["position"] obj.position[2] += obj.get("movez", 0) obj.orientation = i["orientation"] obj["spawned_by"] = i obj["despawn_damping"] = random.randint(100,200) bge.logic.globalDict["all-lights"].append(obj) if obj.get("good"): obj.replaceMesh(obj["good"]) i["to_spawn"] = False # Deleting them when they are far away for obj in bge.logic.globalDict["all-lights"]: objAddress = Opt.Address(obj.position, spawnAtDistance/2) inview = obj.getDistanceTo(cam) < 20 or cam.pointInsideFrustum(obj.position) == cam.INSIDE if objAddress not in camSurround or not inview: if not obj in Reuse.reuse.get(obj.name, []): Reuse.Delete(obj) obj["spawned_by"]["to_spawn"] = True bge.logic.globalDict["all-lights"].remove(obj) break # Fixing broken ones when out of frame lookingAt = random.choice(list(bge.logic.globalDict["light-spawns"].keys())) if lookingAt not in camSurround: listOfLights = bge.logic.globalDict["light-spawns"][lookingAt] theLightToFix = random.choice(listOfLights) if theLightToFix.get("broken"): theLightToFix["broken"] = False print("Fixed", theLightToFix["LightSpawn"], "at:", lookingAt) ##### TREES ###### # Making two pulls of points. # One for where to spawn Trees. # Other for where to take trees from. # Where to put trees trees = bge.logic.globalDict["trees"] PutTreesAt = [] n = 0 for addr in camSurroundCars: for spawnPoint in bge.logic.globalDict["trees"].get(addr, []): n += 1 distance = cam.getDistanceTo(spawnPoint["position"]) PutTreesAt.append([distance, n, spawnPoint]) PutTreesAt = sorted(PutTreesAt) # Where to take trees GetTreesFrom = [] for n, tree in enumerate(bge.logic.globalDict["trees"]["spawned"]): distance = cam.getDistanceTo(tree) GetTreesFrom.append([distance, n, tree]) GetTreesFrom = reversed(sorted(GetTreesFrom)) # Lets actually populate the trees for spawnPoint in PutTreesAt: distance, n, spawnPoint = spawnPoint if not spawnPoint["to_spawn"]: continue inview = cam.pointInsideFrustum(spawnPoint["position"]) == cam.INSIDE tree = None if goodFPS and inview and Reuse.reuse.get(spawnPoint["treeverylow"]): tree = Reuse.Create(spawnPoint["treeverylow"]) tree.position = spawnPoint["position"] tree.orientation = spawnPoint["orientation"] tree.scaling = spawnPoint["scaling"] / 1.603 spawnPoint["to_spawn"] = False tree["spawned_by"] = spawnPoint tree["lod"] = 0 bge.logic.globalDict["trees"]["spawned"].append(tree) break elif goodFPS and inview: for tree in GetTreesFrom: treeDistance, treeN, tree = tree treeInview = cam.pointInsideFrustum(tree.position) == cam.INSIDE or treeDistance > 100 if ( treeDistance > distance or not treeInview ) and tree["spawned_by"]["treeverylow"] == spawnPoint["treeverylow"]: bge.logic.globalDict["trees"]["spawned"].remove(tree) tree["spawned_by"]["to_spawn"] = True Reuse.Delete(tree, inactive=True) tree = None break # And low let's implement the lod system for trees. for tree in GetTreesFrom: treeDistance, treeN, tree = tree inview = cam.pointInsideFrustum(tree.position) == cam.INSIDE newtree = None # Hires if goodFPS and treeDistance <= 50 and Reuse.reuse.get(tree["spawned_by"]["tree"]) and not tree["lod"] == 2 and inview: newtree = Reuse.Create(tree["spawned_by"]["tree"]) newtree["lod"] = 2 # Lowres elif goodFPS and treeDistance > 50 and Reuse.reuse.get(tree["spawned_by"]["treeverylow"]) and not tree["lod"] == 0: newtree = Reuse.Create(tree["spawned_by"]["treeverylow"]) newtree["lod"] = 2 if goodFPS and newtree: newtree.position = tree.position newtree.orientation = tree.orientation newtree.scaling = tree.scaling newtree["spawned_by"] = tree["spawned_by"] #trees["keep"] = random.randint(0,20) Reuse.Delete(tree) bge.logic.globalDict["trees"]["spawned"].append(newtree) bge.logic.globalDict["trees"]["spawned"].remove(tree) break #SpawnsCloseEnough = [] #for i in camSurroundCars: # SpawnsCloseEnough += bge.logic.globalDict["trees"].get(i, []) # #byDistance = [] #for n, i in enumerate(SpawnsCloseEnough): # distance = cam.getDistanceTo(i["position"]) # byDistance.append([distance, n, i]) #byDistance = sorted(byDistance) #bge.logic.globalDict["trees"]["cu"] = byDistance[-1][0] #for i in byDistance: # # distance, n, i = i # #addr = Opt.Address(i["position"], spawnAtDistance) # inmemory = Reuse.reuse.get(i["treeverylow"]) # # inview = True#cam.pointInsideFrustum(i["position"]) == cam.INSIDE # tree = None # # if inmemory and inview and i["to_spawn"]: # ## if i.get("keep"): ## i["keep"] -= 1 ## continue # # tree = Reuse.Create(i["treeverylow"]) # # tree.position = i["position"] # tree.orientation = i["orientation"] # tree.scaling = i["scaling"] / 1.603 # # i["to_spawn"] = False # # tree["spawned_by"] = i # tree["lod"] = 0 # tree["keep"] = 20 # # bge.logic.globalDict["trees"]["spawned"].append(tree) # # elif not inmemory and distance < bge.logic.globalDict["trees"]["cu"]: # bge.logic.globalDict["trees"]["cu"] = distance #byDistance = [] #for n, tree in enumerate(bge.logic.globalDict["trees"]["spawned"]): # # distance = cam.getDistanceTo(tree.position) # byDistance.append([distance, n, tree]) #byDistance = sorted(byDistance) #for tree in reversed(byDistance): # # # distance, n, tree = tree # # addr = Opt.Address(tree.position, spawnAtDistance) # inview = addr in camSurroundCars# and cam.pointInsideFrustum(i["position"]) == cam.INSIDE # # if not inview or distance > bge.logic.globalDict["trees"]["cu"]: # # if tree["keep"]: # tree["keep"] -= 1 # continue # # bge.logic.globalDict["trees"]["spawned"].remove(tree) # Reuse.Delete(tree, inactive=True) # tree["spawned_by"]["to_spawn"] = True # tree["spawned_by"]["keep"] = 20 # break # #for tree in byDistance: # # distance, n, tree = tree # inview = cam.pointInsideFrustum(i["position"]) == cam.INSIDE # # if inview: # # tree["keep"] = 20 # # newtree = None # # if distance <= 70 and Reuse.reuse.get(tree["spawned_by"]["tree"]) and tree["lod"] != 2: # # newtree = Reuse.Create(tree["spawned_by"]["tree"]) # newtree["lod"] = 2 # # # elif distance > 70 and Reuse.reuse.get(tree["spawned_by"]["treeverylow"]) and tree["lod"] != 0: # # newtree = Reuse.Create(tree["spawned_by"]["treeverylow"]) # newtree["lod"] = 0 # # # if newtree: # # newtree.position = tree.position # newtree.orientation = tree.orientation # newtree.scaling = tree.scaling # newtree["spawned_by"] = tree["spawned_by"] # newtree["keep"] = 20 # # Reuse.Delete(tree) # bge.logic.globalDict["trees"]["spawned"].append(newtree) # bge.logic.globalDict["trees"]["spawned"].remove(tree) # break # # 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"]): bge.logic.globalDict["print"] = "Press E to call Elevator." # Pressing E to call it if 27 in bge.logic.globalDict["keys"]: elevator["going_to"] = atLevel(dani) elevator["closing_doors"] = True else: bge.logic.globalDict["print"] = "Press 0-"+str(len(elevator["levels"])-1)+" activate the elevator." numbers = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] 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 else: elevator["elevator"].position[2] += 0.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 = cheat_spawn.sensors["Keyboard"] bge.logic.globalDict["keys"] = [] for key in keys.events: bge.logic.globalDict["keys"].append(key[0]) if keys.events: #print("Key pressed code:",keys.events) if "cheat" not in bge.logic.globalDict: bge.logic.globalDict["cheat"] = [0] for i in keys.events: if i[0] != bge.logic.globalDict["cheat"][-1]: bge.logic.globalDict["cheat"].append(i[0]) # SPAWN CHEATS cheats = { "NeonSpeedsterBox":[36, 27, 37, 36, 41, 38, 27, 26, 41, 42, 27, 40], "RedKissBox":[40, 27, 26, 33, 31, 41], "DarkShadowBox":[26, 23, 40, 33, 41, 30, 23, 26, 37, 45] } for i in cheats: code = bge.logic.globalDict["cheat"][-(len(cheats[i])):] if code == cheats[i]: print("Spawning:", i) car = Reuse.Create(i) car["npc"] = "" car["race"] = "" bge.logic.globalDict["allcars"].append(car) car.position = cheat_spawn.position car.orientation = cheat_spawn.orientation car["underwater"] = False rig = car.children[car.get("rig","RIG")] body = rig.children["Car_body"] body["good"] = body.meshes[0].name bge.logic.globalDict["spawnedCarModels"].append(i) 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 = [ [[-17.86, 899.2, 4.738], [40,23,25,27,42,40,23,25,33]], # Racetrack [[-752.78, -937.4, 411.08], [30, 37, 43, 41, 27]], # House [[-937.3, -277.1, 257.7], [35, 23, 36, 41, 31, 37, 36]],# Mansion [[-2.122, 1322, 99.85],[42, 37, 45, 27, 40, 13]], # Tower0 [[-172.4, 1147, 99.68],[42, 37, 45, 27, 40, 14]], # Tower1 [[200, 1204, 100],[42, 37, 45, 27, 40, 15]], # Tower2 [[12.19, 1127, 139.3],[42, 37, 45, 27, 40, 16]], # Tower3 [[148.4, 941.7, 98.83],[42, 37, 45, 27, 40, 17]], # Tower4 [[-725, -984.6, 409.2],[25, 31, 36, 27, 35, 23]] # Cinema ] for i in teleportations: code = bge.logic.globalDict["cheat"][-(len(i[1])):] if code == i[1]: dani.position = i[0] 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 # 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] Distraction.Explosion(expos, mass=1, size=2) bge.logic.globalDict["print"] = "Boom! , Sir." bge.logic.globalDict["cheat"] = [0] # no ding here, the boom is enough # 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"] if not race["started"] and not dani.get("race") and race["racers"]: 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"]: if dani["driving"]: bge.logic.globalDict["print"] = "Press R to start the race." if keys.events and 40 in keys.events[0]: 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 # 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 car to race." # If this race is going elif dani.get("race") == racename: nextcheck = race["checkpoints"][dani["checkpoint"]] # 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: nextcheckpoint = race["checkpoints"][ ( dani.get("checkpoint") + 1 ) % len(race["checkpoints"]) ] 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 if dani.getDistanceTo(nextcheck["location"]) < nextcheck["radius"]: 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 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 # 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! Time: "+formattedTime # If finished else: bge.logic.globalDict["print"] = "You finished number "+str(race["positions"].index(dani)+1) + " Time: "+formattedTime 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) # Messages if bge.logic.globalDict.get("print") and bge.logic.globalDict.get("last_print") != bge.logic.globalDict["print"]: print("Message:", bge.logic.globalDict["print"]) scene.objects["Messages"]["Text"] = str(bge.logic.globalDict.get("print")) scene.objects["Messages"].playAction("MessagesAction", 0, 100) bge.logic.globalDict["last_print"] = bge.logic.globalDict["print"] bge.logic.globalDict["print"] = "" # 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} # 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", "low":"TheRacetrackLow", "radius":1000, "now":"high" }, "TheCity":{ "object":scene.objects["TheCity"], "high":"TheCityHigh", "low":"TheCityLow", "radius":1500, "now":"high" }, "TheHouse":{ "object":scene.objects["TheHouse"], "high":"TheHouseGood", "low":"TheHouseBorked", "radius":200, "now":"high" }, } chunks = bge.logic.globalDict["LODchunks"] for chunkname in chunks: chunk = chunks[chunkname] if chunk["now"] == "low" and cam.getDistanceTo(chunk["object"]) < chunk["radius"]: print("Making", chunkname, "high") chunk["object"].replaceMesh(chunk["high"]) chunk["object"].restorePhysics() chunk["now"] = "high" elif chunk["now"] == "high" and cam.getDistanceTo(chunk["object"]) > chunk["radius"]: print("Making", chunkname, "low") chunk["object"].replaceMesh(chunk["low"]) if not dani.get("race"): chunk["object"].suspendPhysics() chunk["now"] = "low"