DanisRace/python_dumpster/Main_update_v22-02-2024.py

1327 lines
49 KiB
Python
Raw Normal View History

2024-07-13 15:15:50 +02:00
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"