Skip to content

Instantly share code, notes, and snippets.

@CapsAdmin
Created April 5, 2018 07:10
Show Gist options
  • Save CapsAdmin/a308ba7ab694f5418ba0888eb485c07a to your computer and use it in GitHub Desktop.
Save CapsAdmin/a308ba7ab694f5418ba0888eb485c07a to your computer and use it in GitHub Desktop.
local global_can_play = true
local _wowozela_volume = CLIENT and CreateClientConVar("wowozela_volume","0.5",true,false)
local wowozela_volume = 0.5
wowozela = {}
local wowozela = wowozela
wowozela.thinkers = {}
local thinkers = wowozela.thinkers
function wowozela.RequestThink(ply,wep)
thinkers[ply] = wep
if not wowozela.thinking then
wowozela.thinking = true
hook.Add("Think", "wowozela", wowozela.Think)
end
end
wowozela.ValidNotes =
{
IN_ATTACK,
IN_ATTACK2,
}
wowozela.ValidKeys =
{
IN_ATTACK,
IN_ATTACK2,
IN_WALK,
IN_SPEED,
IN_USE,
}
if(SERVER) then
for key, value in pairs(wowozela.ValidNotes) do
concommand.Add("wowozela_select_" .. key, function(ply, _, args)
local wep = ply:GetActiveWeapon()
if wep:IsValid() and wep:GetClass() == "wowozela" then
local val = tonumber(args[1]) or 1
wep.dt[value] = val
end
end)
end
end
wowozela.Samples = {
"ambient/levels/citadel/field_loop3.wav",
"items/suitcharge1.wav",
"items/medcharge4.wav",
"plats/elevator_move_loop1.wav",
"test/temp/soundscape_test/tv_music.wav",
"ambient/atmosphere/indoor2.wav",
"ambient/atmosphere/laundry_amb.wav",
"ambient/atmosphere/indoor1.wav",
"ambient/atmosphere/tunnel1.wav",
}
for _, file_name in pairs(file.Find("sound/wowozela/samples/*.wav", "GAME")) do
table.insert(wowozela.Samples, "wowozela/samples/" .. file_name)
if SERVER then
resource.AddFile("sound/wowozela/samples/" .. file_name)
end
end
table.sort(wowozela.Samples, function(a,b) return a < b end)
function wowozela.New(ply)
local sampler = setmetatable({}, wowozela.SamplerMeta)
ply.sampler = sampler
sampler.Player = NULL
sampler.Pitch = 100
sampler.Volume = 1
sampler.Keys = {}
sampler.CSP = {}
sampler:Initialize(ply)
return sampler
end
function wowozela.IsValidKey(key)
return table.HasValue(wowozela.ValidKeys, key)
end
function wowozela.IsValidNote(key)
return table.HasValue(wowozela.ValidNotes, key)
end
do -- sample meta
local META = {}
META.__index = META
META.Weapon = NULL
function META:Initialize(ply)
self.Player = ply
for i, path in pairs(wowozela.Samples) do
self:SetSample(i, path)
end
self.IDs = {}
end
function META:GetSampleIndex(key)
if wowozela.IsValidNote(key) then
local wep = self.Player:GetActiveWeapon()
if wep:IsWeapon() and wep.dt and wep:GetClass() == "wowozela" then
return math.Clamp(wep.dt[key], 1, #wowozela.Samples)
end
end
end
function META:CanPlay()
if not global_can_play then return end
local wep = self.Player:GetActiveWeapon()
if wep:IsWeapon() and wep:GetClass() == "wowozela" then
self.Weapon = wep
return true
end
return false
end
function META:GetPos()
if self.Player == LocalPlayer() and not self.Player:ShouldDrawLocalPlayer() then
return self.Player:EyePos()
end
local id = self.Player:LookupBone("ValveBiped.Bip01_Head1")
local pos = id and self.Player:GetBonePosition(id)
return pos or self.Player:EyePos()
end
function META:GetAngles()
local ang = self.Player:GetAimVector():Angle()
ang.p = math.NormalizeAngle(ang.p)
ang.y = math.NormalizeAngle(ang.y)
ang.r = 0
return ang
end
function META:IsPlaying() -- hm
for _, on in pairs(self.Keys) do
if on then
return true
end
end
return false
end
function META:SetSample(i, path)
self.CSP[i] = CreateSound(self.Player, path or wowozela.DefaultSound)
self.CSP[i]:SetSoundLevel(85)
end
function META:ChangeVolume(i, num)
if self.CSP[i] then
self.CSP[i]:ChangeVolume(wowozela_volume * self.Volume, -1)
end
end
function META:ChangePitch(i, num)
if self.CSP[i] then
self.CSP[i]:ChangePitch(self.Pitch, -1)
end
end
function META:SetPitch(num) -- ???
num = num or 1
if self:IsKeyDown(IN_WALK) then
num = num - 1
end
self.Pitch = math.Clamp(math.floor(100 * 2 ^ num), 1, 255)
for i in pairs(wowozela.Samples) do
self:ChangePitch(i, self.Pitch)
end
end
function META:SetVolume(num)
self.Volume = math.Clamp(num or self.Volume, 0.0001, 1)
for i in pairs(wowozela.Samples) do
self:ChangeVolume(i, self.Volume)
end
end
function META:Start(i, id)
if not self:CanPlay() then return end
if self.CSP[i] then
if id then
local snd = self.IDs[id]
if snd then
snd:Stop()
end
snd = self.CSP[i]
snd:PlayEx(self.Volume, self.Pitch)
self.IDs[id] = snd
else
self.CSP[i]:PlayEx(self.Volume, self.Pitch)
end
end
end
function META:Stop(i, id)
if self.CSP[i] then
if id then
local snd = self.IDs[id]
if snd then
snd:Stop()
end
self.IDs[id] = self.CSP[i]
else
self.CSP[i]:Stop()
end
end
end
function META:IsKeyDown(key)
return self.Keys[key] == true
end
function META:OnKeyEvent(key, press)
local id = self:GetSampleIndex(key)
if id then
if press then
if self:IsKeyDown(IN_SPEED) and self.Player == LocalPlayer() then
local ang = self.Player:EyeAngles()
local p = ang.p / 89 -- -1 to 1
p = (p + 1) / 2 -- 0 to 1
p = p * 12 -- 0 to 12
p = math.Round(p*2)/2 -- rounded
p = p / 12
p = (p * 2) - 1
ang.p = p * 89
self.Player:SetEyeAngles(ang)
end
self:Start(id, key)
self:SetVolume(1)
else
self:Stop(id, key)
end
end
end
function META:Think()
if not self:CanPlay() then
for _, csp in pairs(self.CSP) do
csp:Stop()
end
return false
end
local ang = self:GetAngles()
if self:IsKeyDown(IN_USE) then
if self.using then
self:SetVolume(math.abs(ang.y - self.using) / 20)
else
self.using = ang.y
end
else
self.using = false
self:SetVolume(1)
end
self:SetPitch(-ang.p/89)
if self:IsKeyDown(IN_ATTACK) or self:IsKeyDown(IN_ATTACK2) then
self:MakeParticle()
end
return true
end
local emitter
function META:MakeParticle()
local pitch = self.Pitch
emitter = emitter or ParticleEmitter(Vector())
local scale = self.Player:GetModelScale()
local forward = self:GetAngles():Forward()
local particle = emitter:Add("particle/fire", self:GetPos() + forward * 10 * scale)
if particle then
local col = HSVToColor(pitch*2.55, self.Volume, 1)
particle:SetColor(col.r, col.g, col.b, self.Volume)
particle:SetVelocity(self.Volume * self:GetAngles():Forward() * 500 * scale)
particle:SetDieTime(20)
particle:SetLifeTime(0)
local size = ((-pitch + 255) / 250) + 1
particle:SetAngles(AngleRand())
particle:SetStartSize(math.max(size*2*scale, 1) * 1.5)
particle:SetEndSize(0)
particle:SetStartAlpha(255*self.Volume)
particle:SetEndAlpha(0)
--particle:SetRollDelta(math.Rand(-1,1)*20)
particle:SetAirResistance(500)
--particle:SetGravity(Vector(math.Rand(-1,1), math.Rand(-1,1), math.Rand(-1, 1)) * 8 )
end
end
wowozela.SamplerMeta = META
end
do -- player meta
local PLAYER = FindMetaTable("Player")
function PLAYER:GetSampler()
local sampler = self.sampler
if not sampler then sampler = wowozela.New(self) end
return sampler
end
end
do -- hooks
local hack = {}
function wowozela.KeyEvent(ply, key, press)
--WHAT
local id = ply:UniqueID() .. key
if hack[id] == press then return end
hack[id] = press
--WHAT
local sampler = ply:GetSampler()
if sampler and sampler.OnKeyEvent and ply == sampler.Player then
sampler.Keys[key] = press
return sampler:OnKeyEvent(key, press)
end
end
function wowozela.Think()
local vol = _wowozela_volume:GetFloat()
wowozela_volume = math.Clamp(vol,0.01,1)
global_can_play = vol >= 0.01
local me = LocalPlayer()
local sampler = me:IsValid() and me:GetSampler()
if sampler and sampler.Think then
sampler:Think()
end
for key, ply in next,player.GetAll() do
local sampler = ply:GetSampler()
if sampler and sampler.Think then
sampler:Think()
end
end
end
if SERVER then
function wowozela.Think()
for ply, wep in next,thinkers do
if not ply:IsValid() then
thinkers[ ply ] = nil
continue
end
local sampler = ply:GetSampler()
if sampler and sampler.Think then
if not sampler:Think() then
thinkers[ ply ] = nil
end
end
end
local shouldthink = next(thinkers)
if not shouldthink then
hook.Remove("Think", "wowozela")
wowozela.thinking = false
end
end
else
hook.Add("Think", "wowozela", wowozela.Think)
end
if CLIENT then
function wowozela.Draw(depth,sky)
if sky then return end
for key, ply in pairs(player.GetAll()) do
local sampler = ply:GetSampler()
if sampler and sampler.Draw then
sampler:Draw()
end
end
end
hook.Add("PostDrawOpaqueRenderables", "wowozela_draw", wowozela.Draw)
end
function wowozela.BroadcastKeyEvent(ply, key, press, filter)
local rp = RecipientFilter()
rp:AddAllPlayers()
if not filter then
rp:RemovePlayer(ply)
end
umsg.Start("wowozela_keyevent", rp)
umsg.Entity(ply)
umsg.Long(key) -- or short?
umsg.Bool(press)
umsg.End()
end
hook.Add("KeyPress", "wowozela_keypress", function(ply, key)
local wep = ply:GetActiveWeapon()
if wep:IsValid() and wep:GetClass() == "wowozela" and wowozela.IsValidKey(key) then
if SERVER then
wowozela.BroadcastKeyEvent(ply, key, true)
wep:OnKeyEvent(key, true)
end
if CLIENT then
wowozela.KeyEvent(ply, key, true)
end
end
end)
hook.Add("KeyRelease", "wowozela_keyrelease", function(ply, key)
local wep = ply:GetActiveWeapon()
if wep:IsValid() and wep:GetClass() == "wowozela" and wowozela.IsValidKey(key) then
if SERVER then
wowozela.BroadcastKeyEvent(ply, key, false)
wep:OnKeyEvent(key, false)
end
if CLIENT then
wowozela.KeyEvent(ply, key, false)
end
end
end)
if CLIENT then
usermessage.Hook("wowozela_keyevent", function(umr)
local ply = umr:ReadEntity()
local key = umr:ReadLong()
local press = umr:ReadBool()
if ply:IsPlayer() and (not ply:IsMuted() or not press) then
wowozela.KeyEvent(ply, key, press)
end
end)
end
end
do
local SWEP = {Primary = {}, Secondary = {}}
SWEP.ClassName = "wowozela"
local function samplename(sn)
sn=sn:match("^wowozela/samples/(.+)%.wav") or sn:match("/?([^/]-)%.[^%.]+$") or sn
sn=sn and sn:gsub("_"," "):gsub("([^%s])([A-Z])",function(a,b) return ('%s %s'):format(a,b) end)
return sn
end
SWEP.Base = "weapon_base"
SWEP.Author = ""
SWEP.Contact = ""
SWEP.Purpose = ""
SWEP.Instructions = ""
SWEP.PrintName = "Wowozela"
SWEP.Category = "Toys"
SWEP.SlotPos = 1
SWEP.Slot = 1
SWEP.Spawnable = true
SWEP.AutoSwitchTo = true
SWEP.AutoSwitchFrom = true
SWEP.HoldType = "normal"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.DrawAmmo = false
SWEP.DrawCrosshair = true
SWEP.ViewModel = "models/weapons/v_hands.mdl"
SWEP.WorldModel = "models/weapons/w_bugbait.mdl"
SWEP.DrawWeaponInfoBox = true
function SWEP:SetupDataTables()
for i, key in ipairs(wowozela.ValidNotes) do
self:DTVar("Int", i, key)
end
end
function SWEP:DrawWeaponSelection(x,y,w,t,a)
draw.SimpleText("!","hl2mptypedeath",x+w/2,y,Color(255, 220, 0,a),TEXT_ALIGN_CENTER)
end
function SWEP:PrintWeaponInfo() end
function SWEP:DrawWorldModel() return true end
function SWEP:CanPrimaryAttack() return false end
function SWEP:CanSecondaryAttack() return false end
function SWEP:ShouldDropOnDie() return false end
function SWEP:Reload() return false end
function SWEP:Initialize()
if SERVER then
self:SetHoldType("normal")
end
end
function SWEP:Deploy()
wowozela.RequestThink(self:GetOwner(),self)
return true
end
function SWEP:Holster()
if not self:GetOwner():KeyDown(IN_RELOAD) then
return true
end
return false
end
function SWEP:OnKeyEvent(key, press)
end
local gtfo=Vector(1,1,1)*65000
function SWEP:GetViewModelPosition( pos, ang )
return gtfo,ang
end
function SWEP:PreDrawViewModel( )
return true
end
function SWEP:OnDrop()
if SERVER then
self:Remove()
end
end
if CLIENT then
local size = 80
local count = 4
local names = {}
local wason = false
local selection = 1
local alpha = 0
local showing = 5
function SWEP:DrawHUD()
local in1 = self.dt and self.dt[IN_ATTACK] ~= 0 and self.dt[IN_ATTACK] or 1
local in2 = self.dt and self.dt[IN_ATTACK2] ~= 0 and self.dt[IN_ATTACK2] or 1
local left = self:GetOwner():KeyDown(IN_ATTACK) or input.IsMouseDown(MOUSE_LEFT)
local right = self:GetOwner():KeyDown(IN_ATTACK2) or input.IsMouseDown(MOUSE_RIGHT)
local total = #wowozela.Samples
if self:GetOwner():KeyDown(IN_RELOAD) then
if not wason then
gui.EnableScreenClicker(true)
wason = true
end
if left or right then
surface.SetFont("closecaption_bold")
local start = math.max(selection - showing, 1)
local index_end = math.min(selection + showing, total)
local center = showing + 0.5
for I = start, index_end, 1 do
if not names[I] then
local sn = wowozela.Samples[I]
names[I] = samplename(sn)
end
local w,h = surface.GetTextSize(names[I])
local col = HSVToColor(math.abs(selection - I) / center * 90, 1, 1)
surface.SetTextColor(col.r, col.g, col.b, (1 - (math.abs(selection - I)/ center)^2)*255)
surface.SetTextPos(ScrW()/2 - w/2, ScrH() / 2 + h * (I-start) - h * center)
surface.DrawText(names[I])
end
--[[Selection]]
local scale = ScrH() / total
local selected1 = math.Clamp(math.ceil(gui.MouseY()/scale),1,total)
if left and selected1 ~= in1 then
RunConsoleCommand("cmd", "wowozela_select_1", selected1)
end
if right and selected1 ~= in2 then
RunConsoleCommand("cmd", "wowozela_select_2", selected1)
end
selection = selected1
end
else
if(wason) then
gui.EnableScreenClicker(false)
wason = false
end
if not names[in1] then
local sample = wowozela.Samples[in1]
if not sample then error("Missing sample: "..tostring(in1)) end
names[in1] = samplename(sample)
end
if not names[in2] then
local sample = wowozela.Samples[in2]
if not sample then error("Missing sample: "..tostring(in1)) end
names[in2] = samplename(sample)
end
draw.SimpleText(
names[in1],
"closecaption_bold",
16,
ScrH() - ScrH()/2,
HSVToColor((in1/total)*360, 1, 1),
TEXT_ALIGN_LEFT,
TEXT_ALIGN_CENTER
)
draw.SimpleText(
names[in2],
"closecaption_bold",
ScrW() - 16,
ScrH() - ScrH()/2,
HSVToColor((in2/total)*360, 1, 1),
TEXT_ALIGN_RIGHT,
TEXT_ALIGN_CENTER
)
end
end
end
weapons.Register(SWEP, SWEP.ClassName)
end
for k,v in pairs(player.GetAll()) do
v.sampler = nil
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment