Created
September 17, 2021 01:10
-
-
Save NightlyNexus/b008933c0c73ad609c7000ee11513746 to your computer and use it in GitHub Desktop.
A script for the Valve flashlight, meant for VR. This fixes bugs, adds some small features, and cleans up the code from the sample here: https://developer.valvesoftware.com/wiki/SteamVR/Environments/Scripting/flashlight_script_code_full
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Disable this flag to remove the glow particle around the flashlight's lens. | |
local enableGlow = true; | |
local glowParticle; | |
local lightTable = { | |
classname = "light_spot", | |
targetname = "light" .. thisEntity:entindex(), | |
enabled = 0, | |
brightness = "1.5", | |
range = "400", | |
castshadows = "1", | |
shadowtexturewidth = "64", | |
shadowtextureheight = "64", | |
style = "0", | |
fademindist = "0", | |
fademaxdist = "4000", | |
bouncescale = "1.0", | |
renderdiffuse = "1", | |
renderspecular = "1", | |
directlight = "2", | |
indirectlight = "0", | |
attenuation1 = "0.0", | |
attenuation2 = "1.0", | |
innerconeangle = "20", | |
outerconeangle = "32" | |
} | |
local isEquipped = false; | |
local holdingHand; | |
local holdingHandId = -1; -- 0 is right hand. 1 is the left hand. | |
local handAttachment; | |
local player; | |
local flashlightOn = false; | |
local particleTrackpad; | |
local lightEntity; | |
local trackpadX = 0.0; | |
local trackpadY = 0.0; | |
local lightColorsIndex = 13; -- Start at white. | |
local lightColors = {}; | |
lightColors[1] = { 255, 128, 0 }; | |
lightColors[2] = { 255, 0, 0 }; | |
lightColors[3] = { 255, 0, 64 }; | |
lightColors[4] = { 180, 0, 180 }; | |
lightColors[5] = { 64, 0, 180 }; | |
lightColors[6] = { 0, 0, 255 }; | |
lightColors[7] = { 0, 180, 180 }; | |
lightColors[8] = { 0, 255, 128 }; | |
lightColors[9] = { 0, 255, 0 }; | |
lightColors[10] = { 128, 255, 0 }; | |
lightColors[11] = { 255, 255, 0 }; | |
lightColors[12] = { 255, 180, 0 }; | |
lightColors[13] = { 255, 255, 255 }; | |
local colorWheelCount = 12; -- White is at the center of the wheel. | |
local colorWheelMaxDegrees = {}; | |
local equippedStartTime = 0; | |
function SetEquipped(self, pHand, nHandID, pHandAttachment, pPlayer) | |
holdingHand = pHand; | |
holdingHandId = nHandID; | |
handAttachment = pHandAttachment; | |
player = pPlayer; | |
isEquipped = true; | |
equippedStartTime = Time(); | |
local trackpadParticleName = "particles/tool_fx/controller_trackpad_position_dot.vpcf"; | |
particleTrackpad = ParticleManager:CreateParticle(trackpadParticleName, PATTACH_POINT_FOLLOW, handAttachment); | |
ParticleManager:SetParticleControlEnt(particleTrackpad, 0, handAttachment, PATTACH_POINT_FOLLOW, "trackpad_center", Vector(0, 0, 0), true); | |
local degreeChunk = 360.0 / colorWheelCount; | |
for i = 1, colorWheelCount do | |
local maxDegree = i * degreeChunk; | |
colorWheelMaxDegrees[i] = maxDegree; | |
end | |
if (lightEntity == nil) then | |
lightEntity = SpawnEntityFromTableSynchronous(lightTable.classname, lightTable); | |
end | |
lightEntity:SetParent(handAttachment, "flashlight_beam"); | |
lightEntity:SetLocalOrigin(Vector(0, 0, 0)); | |
lightEntity:SetLocalAngles(0, 0, 0); | |
if (flashlightOn) then | |
EntFireByHandle(self, handAttachment, "Skin", "1", 0); | |
end | |
ParticleManager:SetParticleControl(particleTrackpad, 1, Vector(-trackpadY, trackpadX, 0)); | |
ParticleManager:SetParticleControl(particleTrackpad, 2, Vector(lightColors[lightColorsIndex][1], lightColors[lightColorsIndex][2], lightColors[lightColorsIndex][3])); | |
EntFireByHandle(self, lightEntity, "setlightcolor", "" .. lightColors[lightColorsIndex][1] .. " " .. lightColors[lightColorsIndex][2] .. " " .. lightColors[lightColorsIndex][3] .. "", 0); | |
if (enableGlow) then | |
if (flashlightOn) then | |
ParticleManager:DestroyParticle(glowParticle, true); | |
createGlowParticle(handAttachment); | |
end | |
holdingHand:SetThink("FlashlightThink", self, 0.0); | |
end | |
return true; | |
end | |
function SetUnequipped() | |
holdingHand = nil; | |
holdingHandId = -1; | |
handAttachment = nil; | |
player = nil; | |
isEquipped = false; | |
lightEntity:SetParent(thisEntity, "flashlight_beam"); | |
if (particleTrackpad ~= nil) then | |
ParticleManager:DestroyParticle(particleTrackpad, true); | |
particleTrackpad = nil; | |
end | |
if (enableGlow and flashlightOn) then | |
ParticleManager:DestroyParticle(glowParticle, true); | |
createGlowParticle(thisEntity); | |
end | |
return true; | |
end | |
--------------------------------------------------------------------------- | |
-- Get the degrees of an x and y position on a two-dimensional surface. | |
--------------------------------------------------------------------------- | |
function GetDegrees(x, y) | |
local deltaX = 0 - x; | |
local deltaY = 0 - y; | |
local radAngle = math.atan2(deltaY, deltaX); | |
local degreeAngle = radAngle * 180.0 / math.pi; | |
return (180.0 - degreeAngle); | |
end | |
function Precache(context) | |
PrecacheModel("models/props_gameplay/flashlight001.vmdl", context); | |
PrecacheParticle("particles/tool_fx/controller_trackpad_position_dot.vpcf", context); | |
if (enableGlow) then | |
PrecacheParticle("particles/tool_fx/flashlight_thirdperson.vpcf", context); | |
end | |
end | |
function ChangeColor(newLightColorsIndex) | |
if (lightColorsIndex == newLightColorsIndex) then | |
return ; | |
end | |
lightColorsIndex = newLightColorsIndex; | |
if (enableGlow and flashlightOn) then | |
ParticleManager:SetParticleControl(glowParticle, 5, Vector(lightColors[lightColorsIndex][1], lightColors[lightColorsIndex][2], lightColors[lightColorsIndex][3])); | |
end | |
EntFireByHandle(self, lightEntity, "setlightcolor", "" .. lightColors[lightColorsIndex][1] .. " " .. lightColors[lightColorsIndex][2] .. " " .. lightColors[lightColorsIndex][3] .. "", 0); | |
EmitSoundOn("ui_select", thisEntity); | |
end | |
function OnHandleInput(input) | |
local holdingHandIN_TRIGGER = IN_USE_HAND1; | |
if (holdingHandId == 0) then | |
holdingHandIN_TRIGGER = IN_USE_HAND0 | |
end | |
local holdingHandIN_GRIP = IN_GRIP_HAND1; | |
if (holdingHandId == 0) then | |
holdingHandIN_GRIP = IN_GRIP_HAND0 | |
end | |
local holdingHandIN_PAD_TOUCH_HAND = IN_PAD_TOUCH_HAND1; | |
if (holdingHandId == 0) then | |
holdingHandIN_PAD_TOUCH_HAND = IN_PAD_TOUCH_HAND0 | |
end | |
if (input.buttonsDown:IsBitSet(holdingHandIN_PAD_TOUCH_HAND)) then | |
local updateTrackpad = false; | |
local currentTrackpadX = input.trackpadX; | |
if (currentTrackpadX ~= trackpadX) then | |
trackpadX = currentTrackpadX; | |
updateTrackpad = true; | |
end | |
local currentTrackpadY = input.trackpadY; | |
if (currentTrackpadY ~= trackpadY) then | |
trackpadY = currentTrackpadY; | |
updateTrackpad = true; | |
end | |
if (updateTrackpad) then | |
UpdateTrackpadPosition(); | |
end | |
end | |
if (input.buttonsPressed:IsBitSet(holdingHandIN_TRIGGER)) then | |
input.buttonsPressed:ClearBit(holdingHandIN_TRIGGER); | |
-- Add a delay to prevent the flashlight from turning on when picked up with the trigger. | |
if (Time() > equippedStartTime + 0.2) then | |
ToggleFlashlight(); | |
end | |
end | |
if (input.buttonsReleased:IsBitSet(holdingHandIN_TRIGGER)) then | |
input.buttonsReleased:ClearBit(holdingHandIN_TRIGGER); | |
end | |
if (input.buttonsReleased:IsBitSet(holdingHandIN_GRIP)) then | |
input.buttonsReleased:ClearBit(holdingHandIN_GRIP); | |
thisEntity:ForceDropTool(); | |
end | |
return input; | |
end | |
function UpdateTrackpadPosition() | |
local degree = GetDegrees(trackpadX, trackpadY); | |
local distance = math.sqrt((trackpadX ^ 2) + (trackpadY ^ 2)); | |
if (distance < 0.24) then | |
-- The center of the trackpad is the white selection. | |
ChangeColor(13); | |
else | |
local minDegree = 0 | |
for i = 1, colorWheelCount do | |
local maxDegree = colorWheelMaxDegrees[i]; | |
if (degree >= minDegree and degree < maxDegree) then | |
ChangeColor(i); | |
break ; | |
end | |
minDegree = maxDegree; | |
end | |
end | |
ParticleManager:SetParticleControl(particleTrackpad, 1, Vector(-trackpadY, trackpadX, 0)); | |
ParticleManager:SetParticleControl(particleTrackpad, 2, Vector(lightColors[lightColorsIndex][1], lightColors[lightColorsIndex][2], lightColors[lightColorsIndex][3])); | |
end | |
function ToggleFlashlight() | |
if (flashlightOn) then | |
TurnFlashlightOff() | |
else | |
TurnFlashlightOn(); | |
end | |
holdingHand:FireHapticPulse(1); -- 1 is the heavy rumble. | |
end | |
function TurnFlashlightOn() | |
flashlightOn = true; | |
-- Borrow the drone sound. | |
EmitSoundOn("drone_equip", thisEntity); | |
EntFireByHandle(self, handAttachment, "Skin", "1", 0); | |
EntFireByHandle(self, thisEntity, "Skin", "1", 0); | |
EntFireByHandle(self, lightEntity, "TurnOn", "", 0); | |
if (enableGlow) then | |
createGlowParticle(handAttachment); | |
end | |
end | |
function TurnFlashlightOff() | |
flashlightOn = false; | |
-- Borrow the drone sound. | |
EmitSoundOn("drone_equip", thisEntity); | |
EntFireByHandle(self, handAttachment, "Skin", "0", 0); | |
EntFireByHandle(self, thisEntity, "Skin", "0", 0); | |
EntFireByHandle(self, lightEntity, "TurnOff", "", 0); | |
if (enableGlow) then | |
ParticleManager:DestroyParticle(glowParticle, true); | |
glowParticle = nil; | |
end | |
end | |
function createGlowParticle(owningEntity) | |
local modelAttachmentIndex = owningEntity:ScriptLookupAttachment("flashlight_beam"); | |
local vecStartPos = owningEntity:GetAttachmentOrigin(modelAttachmentIndex); | |
local direction = -owningEntity:GetForwardVector(); | |
local vecEndPos = vecStartPos + (direction * 140); | |
local glowParticleName = "particles/tool_fx/flashlight_thirdperson.vpcf"; | |
glowParticle = ParticleManager:CreateParticle(glowParticleName, PATTACH_POINT_FOLLOW, owningEntity); | |
ParticleManager:SetParticleControlEnt(glowParticle, 1, owningEntity, PATTACH_POINT_FOLLOW, "flashlight_beam", Vector(0, 0, 0), true); | |
ParticleManager:SetParticleControl(glowParticle, 2, vecEndPos); | |
ParticleManager:SetParticleControl(glowParticle, 5, Vector(lightColors[lightColorsIndex][1], lightColors[lightColorsIndex][2], lightColors[lightColorsIndex][3])); | |
end | |
function FlashlightThink() | |
if (flashlightOn) then | |
local owningEntity = thisEntity; | |
if (isEquipped) then | |
owningEntity = handAttachment; | |
end | |
local modelAttachmentIndex = owningEntity:ScriptLookupAttachment("flashlight_beam"); | |
local vecStartPos = owningEntity:GetAttachmentOrigin(modelAttachmentIndex); | |
local direction = -owningEntity:GetForwardVector(); | |
local vecEndPos = vecStartPos + (direction * 140); | |
ParticleManager:SetParticleControlEnt(glowParticle, 1, owningEntity, PATTACH_POINT_FOLLOW, "flashlight_beam", Vector(0, 0, 0), true); | |
ParticleManager:SetParticleControl(glowParticle, 2, vecEndPos); | |
end | |
return 0.01; | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment