516 lines
17 KiB
Python
516 lines
17 KiB
Python
# GPLv3 or any later version
|
|
# (C) J.Y.Amihud ( blenderdumbass )
|
|
|
|
# This file will dealwith tools and stuff.
|
|
|
|
import bge
|
|
import bpy
|
|
import aud
|
|
import math
|
|
import mathutils
|
|
|
|
from Scripts import Reuse
|
|
|
|
from Scripts.Common import *
|
|
|
|
from Scripts import Vehicle
|
|
from Scripts import Script
|
|
from Scripts import Garage
|
|
|
|
def MainLoop():
|
|
|
|
keys = bge.logic.globalDict["keys"]
|
|
mouse = bge.logic.globalDict["mouse"]
|
|
|
|
scene = bge.logic.getCurrentScene()
|
|
dani = scene.objects["Dani_Box"]
|
|
|
|
if dani.get("driving"):
|
|
return
|
|
|
|
camera = scene.active_camera
|
|
hand = scene.objects["Tool_Hand"]
|
|
hc = scene.objects["Health_Circle"]
|
|
|
|
box = scene.objects["Boxify"]
|
|
if box.get("timer"): box["timer"] -= 1
|
|
else: box.position = [0,0,-1000]
|
|
|
|
# If dani is using a fix tool
|
|
if str(dani.get("tool")) == "FixTool":
|
|
|
|
dis = 10000
|
|
car = None
|
|
|
|
for thecar in bge.logic.globalDict["allcars"]:
|
|
cd = thecar.getDistanceTo(dani)
|
|
if cd < dis:
|
|
dis = cd
|
|
car = thecar
|
|
|
|
ray = DaniPoint(dani, camera)
|
|
|
|
found = False
|
|
|
|
if car:
|
|
|
|
# First we gonna create a list of all objects
|
|
# that the car can get fixed.
|
|
|
|
attachment = dani.get("tool-attachment")
|
|
|
|
objs = []
|
|
|
|
if not Vehicle.OnGround(car):
|
|
objs = [car]
|
|
|
|
for wheel in car["wheels"]:
|
|
if ( wheel.visible and not attachment ) or attachment == "Wheels" :
|
|
objs.append(wheel)
|
|
|
|
for door in car.get("doors", []):
|
|
if ( door.visible and not attachment ) or attachment == "Parts" :
|
|
objs.append(door)
|
|
|
|
if "NitroCanProxy" in car.childrenRecursive and\
|
|
(( not car.get("NitroCan") and attachment == "Nitros") or ( car.get("NitroCan") and not attachment )):
|
|
objs.append(car.childrenRecursive["NitroCanProxy"])
|
|
|
|
if "SpoilerProxy" in car.childrenRecursive and\
|
|
( ( not car.get("Spoiler") and "Spoiler" in str(attachment) ) or ( car.get("Spoiler") and not attachment )):
|
|
objs.append(car.childrenRecursive["SpoilerProxy"])
|
|
|
|
if ray[1]:
|
|
|
|
point = ray[1]
|
|
d = 5
|
|
c = None
|
|
for obj in objs:
|
|
od = obj.getDistanceTo(point)
|
|
if od < d:
|
|
d = od
|
|
c = obj
|
|
|
|
if c:
|
|
found = True
|
|
|
|
if c not in car["wheels"]:
|
|
center = Boxify(c)
|
|
else:
|
|
center = Boxify(c, True)
|
|
|
|
text = ""
|
|
if c in car["wheels"]:
|
|
text = "Wheel"
|
|
|
|
elif str(c) == "NitroCanProxy":
|
|
text = "Nitros"
|
|
|
|
elif "Spoiler" in str(c):
|
|
text = "Spoiler"
|
|
|
|
elif c == car:
|
|
text = "Engine and Chassis"
|
|
|
|
elif c in car["doors"]:
|
|
text = "Bodywork"
|
|
|
|
orange = range(len(text))
|
|
text = text + "\n" + str(int(round(c.get("health", 1.0)*100)))+"%"
|
|
|
|
Script.StatusText(text, orange)
|
|
|
|
# Activate the tool
|
|
if mousecodes["LMB"] in mouse:
|
|
|
|
FixToolSound()
|
|
|
|
if str(c) == "NitroCanProxy":
|
|
Vehicle.AddNitroCan(car)
|
|
dani["tool-attachment"] = None
|
|
car["nitro"] = 10.0
|
|
|
|
if str(c) == "SpoilerProxy" and attachment:
|
|
spoilertype = Garage.shop.get(attachment, {}).get("usemodel")
|
|
Vehicle.AddSpoiler(car, spoilertype)
|
|
dani["tool-attachment"] = None
|
|
|
|
c["health"] = c.get("health", 1.0) + 0.01
|
|
if c["health"] >= 1.0:
|
|
c["health"] = 1.0
|
|
|
|
# Replacing mesh, to looks nice.
|
|
if c.get("Good"):
|
|
c.replaceMesh(c.get("Good"))
|
|
|
|
# Doors
|
|
if c in car["doors"]:
|
|
c["locked"] = True
|
|
|
|
rot = door.orientation.to_euler()
|
|
for i in range(3):
|
|
if i == door.get("axis",2):
|
|
rot[i] = door.get("lockat", 0)
|
|
else:
|
|
rot[i] = 0
|
|
c.orientation = rot
|
|
c.suspendPhysics()
|
|
|
|
door.orientation = rot
|
|
|
|
if c == car:
|
|
Vehicle.ChangeBody(car, good=True)
|
|
|
|
if c == car:
|
|
car["blown"] = False
|
|
|
|
if c["health"] > 0.2:
|
|
|
|
if not c.visible:
|
|
dani["tool-attachment"] = None
|
|
c.visible = True
|
|
|
|
# Removing parts
|
|
if mousecodes["RMB"] in mouse:
|
|
|
|
FixToolSound()
|
|
|
|
# Removing spoilers
|
|
if str(c) == "SpoilerProxy" and not attachment:
|
|
spoilertype = Vehicle.RemoveSpoiler(car)
|
|
for name in Garage.shop:
|
|
item = Garage.shop[name]
|
|
if item.get("usemodel") == spoilertype:
|
|
dani["tool-attachment"] = name
|
|
|
|
# Removing nitros
|
|
if str(c) == "NitroCanProxy" and not attachment:
|
|
Vehicle.RemoveNitroCan(car)
|
|
dani["tool-attachment"] = "Nitros"
|
|
|
|
# Removing bodywork
|
|
if c in car["doors"] and not attachment:
|
|
c["health"] = 0.0
|
|
c.visible = False
|
|
dani["tool-attachment"] = "Parts"
|
|
|
|
# Removing wheels
|
|
elif c in car["wheels"] and not attachment:
|
|
c["health"] = 0.0
|
|
c.visible = False
|
|
dani["tool-attachment"] = "Wheels"
|
|
|
|
|
|
# Shelf
|
|
|
|
if not found:
|
|
|
|
tool = dani["tool"]
|
|
|
|
closest = 5
|
|
theitem = ""
|
|
themodel = None
|
|
|
|
for name in Garage.inventory:
|
|
|
|
amount = Garage.inventory[name]
|
|
item = Garage.shop.get(name, {})
|
|
model = item.get('model')
|
|
if model: model= scene.objects[model]
|
|
|
|
if ( amount or name == dani.get("tool-attachment") ) and model:
|
|
|
|
d = dani.getDistanceTo(model)
|
|
if d < closest:
|
|
closest = d
|
|
theitem = name
|
|
themodel = model
|
|
|
|
if themodel:
|
|
|
|
name = theitem
|
|
amount = Garage.inventory[name]
|
|
item = Garage.shop.get(name, {})
|
|
printname = item.get("name", name)
|
|
|
|
|
|
Boxify(themodel)
|
|
Script.StatusText(printname+"\nIn Stock: "+str(amount), range(len(printname)))
|
|
|
|
if mousecodes["LMB"] in mouse and not tool.get("active-timer"):
|
|
tool["active-timer"] = 30
|
|
|
|
print("pressed", dani.get("tool-attachment"))
|
|
|
|
if not dani.get("tool-attachment"):
|
|
|
|
dani["tool-attachment"] = name
|
|
Garage.Use(name)
|
|
|
|
else:
|
|
|
|
name = dani["tool-attachment"]
|
|
|
|
if name not in Garage.inventory: Garage.inventory[name] = 1
|
|
else: Garage.inventory[name] += 1
|
|
Garage.UpdateShelfs()
|
|
|
|
dani["tool-attachment"] = None
|
|
|
|
# If not model
|
|
else:
|
|
|
|
ray = DaniPoint(dani, camera)
|
|
|
|
if dani.get("tool-attachment"):
|
|
|
|
# Telling the user that her can drop the part
|
|
|
|
if ray[1]:
|
|
box.position = ray[1]
|
|
box.position.z += 1
|
|
box.scaling = (1,1,1)
|
|
|
|
# Dropping the part
|
|
if mousecodes["LMB"] in mouse and ray[1] and not tool.get("active-timer"):
|
|
|
|
name = dani["tool-attachment"]
|
|
item = Garage.shop.get(name, {})
|
|
usemodel = item.get("usemodel")
|
|
dropmodel = Reuse.Create(usemodel)
|
|
dropmodel.position = box.position
|
|
dropmodel.blenderObject["MainColor"] = [1.000000, 0.008796, 0.000000]
|
|
dropmodel.blenderObject["SecondaryColor"] = [1.000000, 0.500000, 0.000000]
|
|
|
|
# Remembering what it was
|
|
dropmodel["tool-attachment"] = dani["tool-attachment"]
|
|
|
|
if "dropped" not in bge.logic.globalDict:
|
|
bge.logic.globalDict["dropped"] = []
|
|
|
|
bge.logic.globalDict["dropped"].append(dropmodel)
|
|
|
|
|
|
dani["tool-attachment"] = None
|
|
tool["active-timer"] = 10
|
|
|
|
elif ray[1]:
|
|
|
|
closest = None
|
|
cldist = 10000
|
|
|
|
for dropmodel in bge.logic.globalDict.get("dropped", []):
|
|
|
|
distance = dropmodel.getDistanceTo(ray[1])
|
|
if distance < cldist:
|
|
closest = dropmodel
|
|
cldist = distance
|
|
|
|
if closest:
|
|
dropmodel = closest
|
|
Boxify(dropmodel)
|
|
|
|
# Taking it back
|
|
if ( mousecodes["LMB"] in mouse or mousecodes["RMB"] in mouse ) and not tool["active-timer"]:
|
|
dani["tool-attachment"] = dropmodel.get("tool-attachment")
|
|
Reuse.Delete(dropmodel)
|
|
tool["active-timer"] = 10
|
|
|
|
|
|
|
|
|
|
|
|
if tool.get("active-timer"): tool["active-timer"] -= 1
|
|
|
|
# Tool attachment
|
|
if dani.get("tool-attachment"):
|
|
|
|
name = dani["tool-attachment"]
|
|
item = Garage.shop.get(name, {})
|
|
usemodel = item.get("usemodel")
|
|
|
|
if not dani.get("tool-attachment-model") and usemodel:
|
|
|
|
dani["tool-attachment-model"] = Reuse.Create(usemodel)
|
|
dani["tool-attachment-model"].suspendPhysics()
|
|
dani["tool-attachment-model"].blenderObject["MainColor"] = [1.000000, 0.008796, 0.000000]
|
|
dani["tool-attachment-model"].blenderObject["SecondaryColor"] = [1.000000, 0.500000, 0.000000]
|
|
|
|
s = item.get("usescale", 1)
|
|
dani["tool-attachment-model"].scaling = [s,s,s]
|
|
|
|
|
|
else:
|
|
|
|
usemodel = dani["tool-attachment-model"]
|
|
usemodel.position = Vehicle.RelativePoint(dani, (-0.5,-0.5,0.5))
|
|
usemodel.applyRotation((0.03,-0.01,0.05),False)
|
|
|
|
elif dani.get("tool-attachment-model"):
|
|
Reuse.Delete(dani["tool-attachment-model"])
|
|
dani["tool-attachment-model"] = None
|
|
|
|
|
|
# If dani is using a paint tool
|
|
elif str(dani.get("tool")) == "PaintTool":
|
|
|
|
ray = DaniPoint(dani, camera)
|
|
tool = dani["tool"]
|
|
|
|
if ray[0] in bge.logic.globalDict["allcars"]:
|
|
|
|
car = ray[0]
|
|
Boxify(car)
|
|
if mousecodes["LMB"] in mouse:
|
|
|
|
PaintToolSound()
|
|
|
|
if not tool.get("active-timer"):
|
|
Vehicle.SmartColor(car, "pallete")
|
|
tool["active-timer"] = 30
|
|
|
|
elif mousecodes["RMB"] in mouse:
|
|
|
|
PaintToolSound()
|
|
|
|
if not tool.get("active-timer"):
|
|
Vehicle.SmartColor(car)
|
|
tool["active-timer"] = 30
|
|
|
|
if tool.get("active-timer"): tool["active-timer"] -= 1
|
|
|
|
def UpdateTool(tool):
|
|
|
|
|
|
tool = tool.owner
|
|
scene = bge.logic.getCurrentScene()
|
|
dani = scene.objects["Dani_Box"]
|
|
hand = scene.objects["Tool_Hand"]
|
|
box = scene.objects["Boxify"]
|
|
icon = scene.objects["Dani_Tool_Icon"]
|
|
|
|
if "taken" not in tool:
|
|
tool["taken"] = None
|
|
tool["wasat"] = tool.position.copy()
|
|
|
|
if not tool["taken"]:
|
|
|
|
if dani.getDistanceTo(tool["wasat"]) < 2 and not tool.get("timer") and not dani.get("tool"):
|
|
tool["taken"] = dani
|
|
tool["timer"] = 100
|
|
dani["tool"] = tool
|
|
|
|
tool.position = hand.position
|
|
tool.orientation = hand.orientation
|
|
tool.setParent(hand, True)
|
|
|
|
icon.blenderObject["raw"] = tool.get("icon_raw", 1)
|
|
icon.blenderObject["column"] = tool.get("icon_column", 0)
|
|
|
|
tool.applyRotation([0,0,0.1], False)
|
|
|
|
elif dani.getDistanceTo(tool["wasat"]) < 2 and not tool.get("timer"):
|
|
|
|
tool["taken"] = None
|
|
tool["timer"] = 100
|
|
dani["tool"] = None
|
|
box.position = [0,0,-1000]
|
|
|
|
tool.removeParent()
|
|
|
|
tool.position = tool["wasat"]
|
|
tool.orientation = [0,0,0]
|
|
|
|
Script.StatusText(" ")
|
|
|
|
icon.blenderObject["raw"] = 1
|
|
icon.blenderObject["column"] = 0
|
|
|
|
if tool.get("timer"): tool["timer"] -= 1
|
|
|
|
def Boxify(obj, orcenter=False):
|
|
|
|
# This function will draw a box around the object
|
|
|
|
scene = bge.logic.getCurrentScene()
|
|
box = scene.objects["Boxify"]
|
|
box["timer"] = 10
|
|
|
|
if not orcenter:
|
|
|
|
# Finding bounding box
|
|
bbox = obj.blenderObject.bound_box
|
|
|
|
# finding the center of the box
|
|
center = 0.125 * sum((mathutils.Vector(b) for b in bbox), mathutils.Vector())
|
|
|
|
center.rotate(obj.orientation)
|
|
center * obj.scaling
|
|
center = obj.position + center
|
|
box.position = center
|
|
|
|
|
|
else:
|
|
box.position = obj.position
|
|
center = obj.position
|
|
box.orientation = obj.orientation
|
|
box.scaling = obj.blenderObject.dimensions
|
|
|
|
|
|
return center
|
|
|
|
def DaniPoint(dani, camera):
|
|
|
|
# Then we want to see if any of them are pointed at
|
|
fro = dani.position.copy()
|
|
fro.z += 1
|
|
|
|
to = fro.copy()
|
|
to.z -= 1
|
|
to -= fro
|
|
to.rotate(camera.worldOrientation.to_euler())
|
|
to += fro
|
|
|
|
ray = Vehicle.BeautyRayCast(dani, "tool", to, fro, dist=5)
|
|
|
|
return ray
|
|
|
|
|
|
#### SOUNDS #####
|
|
|
|
def FixToolSound():
|
|
|
|
# Engine Sound
|
|
|
|
device = bge.logic.globalDict["SoundDevice"]
|
|
|
|
code = "//sfx/fixtool.ogg"
|
|
if code not in bge.logic.globalDict["sounds"]:
|
|
bge.logic.globalDict["sounds"][code] = {"sound":aud.Sound(bge.logic.expandPath(code)),
|
|
"play":None}
|
|
|
|
sound = bge.logic.globalDict["sounds"][code]
|
|
|
|
if not sound["play"] or not sound["play"].status:
|
|
sound["play"] = device.play(sound["sound"])
|
|
|
|
sound["play"].volume = 1
|
|
|
|
def PaintToolSound():
|
|
|
|
# Engine Sound
|
|
|
|
device = bge.logic.globalDict["SoundDevice"]
|
|
|
|
code = "//sfx/painttool.ogg"
|
|
if code not in bge.logic.globalDict["sounds"]:
|
|
bge.logic.globalDict["sounds"][code] = {"sound":aud.Sound(bge.logic.expandPath(code)),
|
|
"play":None}
|
|
|
|
sound = bge.logic.globalDict["sounds"][code]
|
|
|
|
if not sound["play"] or not sound["play"].status:
|
|
sound["play"] = device.play(sound["sound"])
|
|
|
|
sound["play"].volume = 1
|
|
|