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