DanisRace/Scripts/Tools.py
Victorious Children Studios db92590087 Version 08-08-24
2024-08-27 15:34:26 +03:00

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