DanisRace/python_dumpster/Main_update_v22-02-2024.py
Victorious Children Studios 594e088a83 07-07-24
2024-07-13 16:15:50 +03:00

1327 lines
49 KiB
Python

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"