This commit is contained in:
lifestorm
2024-08-04 23:54:45 +03:00
parent 0e770b2b49
commit df294d03aa
7526 changed files with 4011945 additions and 15 deletions

View File

@@ -0,0 +1,13 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
print("MOMO MODULE DEPRECATED!")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
-- Convars
pk_pills.convars = {}
-- Admin vars
pk_pills.convars.admin_restrict = CreateConVar("pk_pill_admin_restrict", game.IsDedicated() and 1 or 0, FCVAR_REPLICATED + FCVAR_NOTIFY, "Restrict morphing to admins.")
pk_pills.convars.admin_anyweapons = CreateConVar("pk_pill_admin_anyweapons", 0, FCVAR_REPLICATED, "Allow use of any weapon when morphed.")
pk_pills.convars.preserve = CreateConVar("pk_pill_preserve", 0, FCVAR_REPLICATED, "Makes player spit out pills when they unmorph or die.")
-- Client vars
if CLIENT then
pk_pills.convars.cl_thirdperson = CreateClientConVar("pk_pill_cl_thirdperson", 1)
pk_pills.convars.cl_hidehud = CreateClientConVar("pk_pill_cl_hidehud", 0)
end
-- Admin var setter command.
if SERVER then
local function admin_set(ply, cmd, args)
if not ply then
print("If you are using the server console, you should set the variables directly!")
return
end
if not ply:IsSuperAdmin() then
ply:PrintMessage(HUD_PRINTCONSOLE, "You must be a super admin to use this command.")
return
end
local var = args[1]
local value = args[2]
if not var then
if ply then
ply:PrintMessage(HUD_PRINTCONSOLE, "Please supply a valid convar name. Do not include 'pk_pill_admin_'.")
end
return
elseif not ConVarExists("pk_pill_admin_" .. var) then
ply:PrintMessage(HUD_PRINTCONSOLE, "Convar 'pk_pill_admin_" .. var .. "' does not exist. Please supply a valid convar name. Do not include 'pk_pill_admin_'.")
return
end
if not value then
ply:PrintMessage(HUD_PRINTCONSOLE, "Please supply a value to set the convar to.")
return
end
RunConsoleCommand("pk_pill_admin_" .. var, value)
end
concommand.Add("pk_pill_admin_set", admin_set, nil, "Helper command for setting Morph Mod admin convars. Available to super admins.")
end

View File

@@ -0,0 +1,19 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
if CLIENT then
function pk_pills.join_prompt(name, addr)
Derma_Query("Are you sure you want to join '" .. name .. "'?\nWARNING: You will exit your current game!", "", "Yes", function()
LocalPlayer():ConCommand("connect " .. addr)
end, "No")
end
end

View File

@@ -0,0 +1,66 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
custom={}
if SERVER then
function custom.meleeEx(ply,ent,tbl)
-- Small edit that can use a custom dmgType and doesn't force an animation, for morphs with multiple attacks in a single anim
if !ply:IsOnGround() then return end
timer.Simple(tbl.delay,function() if !IsValid(ent) then return end
if !IsValid(ent) then return end
if ply:TraceHullAttack(ply:EyePos(), ply:EyePos()+ply:EyeAngles():Forward()*tbl.range,
Vector(-10,-10,-10),Vector(10,10,10),tbl.dmg,tbl.dmgType,0.1,true) then
ent:PillSound("melee_hit")
else
ent:PillSound("melee_miss")
end
end)
end
function custom.LocoAnim(ply,ent,anim)
-- New function that uses animation locomotion (ish)
if !ply:IsOnGround() then return end
ent:PillAnim(anim,true)
local seq,dur = ent:GetPuppet():LookupSequence(ent.formTable.anims.default[anim])
local ga,gb,gc = ent:GetPuppet():GetSequenceMovement(seq,0,1)
if not ga then print("ga failed") return end -- The animation has no locomotion or it's invalid or we failed in some other way.
local pos = ply:GetPos()
local trin = {}
trin.maxs = Vector(16, 16, 72)
trin.mins = Vector(-16, -16, 0)
trin.start = ply:EyePos()
trin.endpos = gb
trin.filter = {ply, ent, ent:GetPuppet()}
local trout = util.TraceHull(trin)
local gd_prev = ent:GetPuppet():GetCycle()
for i=1,dur*1000 do
timer.Simple(0.001*i,function()
if !IsValid(ent) then return end
if ply:GetPos() == trout.HitPos then return end -- Avoid going through walls if possible chief.
local gd_cur = ent:GetPuppet():GetCycle()
local ga2,gb2,gc2 = ent:GetPuppet():GetSequenceMovement(seq,gd_prev,gd_cur)
gd_prev = gd_cur
if not ga2 then print("ga failed") return end
if gd_cur==0 then return end
if !util.IsInWorld(ply:LocalToWorld(gb2)) then return end
ply:SetPos(ply:LocalToWorld(gb2))
ply:SetAngles(ply:LocalToWorldAngles(gc2))
end)
end
end
end

View File

@@ -0,0 +1,103 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
-- Does what compat.lua used to without being so aggressive about compatability.
-- If another addon wants to break things, IT CAN!
AddCSLuaFile()
-- This will let us use the noclip key to exit morphs,
-- while letting other mods that disable noclip do their thing.
if CLIENT then
local noclip_btns = {}
for i = KEY_FIRST, BUTTON_CODE_LAST do
if input.LookupKeyBinding(i) == "noclip" then
table.insert(noclip_btns, i)
end
end
hook.Add("CreateMove", "momo_exit_check", function()
if vgui.GetKeyboardFocus() == nil and not gui.IsGameUIVisible() then
for _, key in pairs(noclip_btns) do
if input.WasKeyPressed(key) then
timer.Simple(0, function()
RunConsoleCommand("pk_pill_restore")
end)
break
end
end
end
end)
end
-- Still dont let people noclip while morphed
hook.Add("PlayerNoClip", "momo_block_noclip", function(ply)
if IsValid(pk_pills.getMappedEnt(ply)) then return false end
end)
-- Them hooks
hook.Add("CalcView", "momo_calcview", function(ply, pos, ang, fov, nearZ, farZ)
local ent = pk_pills.getMappedEnt(LocalPlayer())
if IsValid(ent) and ply:GetViewEntity() == ply then
local startpos
if ent.formTable.type == "phys" then
startpos = ent:LocalToWorld(ent.formTable.camera and ent.formTable.camera.offset or Vector(0, 0, 0))
else
startpos = pos
end
if pk_pills.convars.cl_thirdperson:GetBool() then
local dist
if ent.formTable.type == "phys" and ent.formTable.camera and ent.formTable.camera.distFromSize then
dist = ent:BoundingRadius() * 5
else
dist = ent.formTable.camera and ent.formTable.camera.dist or 100
end
local underslung = ent.formTable.camera and ent.formTable.camera.underslung
local offset = LocalToWorld(Vector(-dist, 0, underslung and -dist / 5 or dist / 5), Angle(0, 0, 0), Vector(0, 0, 0), ang)
local tr = util.TraceHull({
start = startpos,
endpos = startpos + offset,
filter = ent.camTraceFilter,
mins = Vector(-5, -5, -5),
maxs = Vector(5, 5, 5),
mask = MASK_VISIBLE
})
local view = {}
view.origin = tr.HitPos
view.angles = ang
view.fov = fov
view.drawviewer = true
--[[else
local view = {}
view.origin = startpos
view.angles = ang
view.fov = fov
return view]]
return view
end
end
end)
--[[
hook.Add("CalcViewModelView","momo_calcviewmodel",function(wep,vm,oldPos,oldAng,pos,ang)
local ent = pk_pills.getMappedEnt(LocalPlayer())
local ply = wep.Owner
if (IsValid(ent) and ply:GetViewEntity()==ply and pk_pills.convars.cl_thirdperson:GetBool()) then
return oldPos+oldAng:Forward()*-1000,ang
end
end)]]

View File

@@ -0,0 +1,70 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
local restricted
if SERVER then
util.AddNetworkString("pk_pill_restricted")
-- rename old file
if file.Exists("pill_config/restrictions.txt", "DATA") then
file.Rename("pill_config/restrictions.txt", "pill_config/restricted.txt")
end
-- load restrictions
restricted = {}
for k, v in pairs(("\n"):Explode(file.Read("pill_config/restricted.txt") or "")) do
restricted[v] = true
end
pk_pills._restricted = restricted
concommand.Add("pk_pill_restrict", function(ply, cmd, args, str)
if not ply:IsSuperAdmin() then return end
local pill = args[1]
local a = args[2]
if a == "on" then
restricted[pill] = true
elseif a == "off" then
restricted[pill] = false
end
local write_str = ""
for k, v in pairs(restricted) do
if write_str ~= "" then
write_str = write_str .. "\n"
end
write_str = write_str .. k
end
file.Write("pill_config/restricted.txt", write_str)
net.Start("pk_pill_restricted")
net.WriteTable(restricted)
net.Broadcast()
end)
hook.Add("PlayerInitialSpawn", "pk_pill_transmit_restricted", function(ply)
net.Start("pk_pill_restricted")
net.WriteTable(restricted)
net.Send(ply)
end)
else
pk_pills._restricted = {}
net.Receive("pk_pill_restricted", function(len, pl)
restricted = net.ReadTable()
pk_pills._restricted = restricted
end)
end

View File

@@ -0,0 +1,206 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local npc_sides = {
npc_advisor = "hl_combine",
npc_alyx = "default",
npc_antlion = "hl_antlion",
npc_antlion_grub = "hl_antlion",
npc_antlionguard = "hl_antlion",
npc_barnacle = "wild",
npc_antlion_worker = "hl_antlion",
npc_barney = "default",
npc_breen = "hl_combine",
npc_citizen = "default",
npc_clawscanner = "hl_combine",
npc_combine_camera = "hl_combine",
npc_combine_s = "hl_combine",
npc_combinedropship = "hl_combine",
npc_combinegunship = "hl_combine",
npc_crow = "harmless",
npc_cscanner = "hl_combine",
npc_dog = "default",
npc_eli = "default",
npc_fastzombie = "hl_zombie",
npc_fastzombie_torso = "hl_zombie",
npc_fisherman = "default",
npc_gman = "harmless",
npc_headcrab = "hl_zombie",
npc_headcrab_black = "hl_zombie",
npc_headcrab_fast = "hl_zombie",
npc_helicopter = "hl_combine",
npc_hunter = "hl_combine",
npc_ichthyosaur = "wild",
npc_kleiner = "default",
npc_magnusson = "default",
npc_manhack = "hl_combine",
npc_metropolice = "hl_combine",
npc_monk = "default",
npc_mossman = "default",
npc_pigeon = "harmless",
npc_poisonzombie = "hl_zombie",
npc_rollermine = "hl_combine",
npc_seagull = "harmless",
npc_sniper = "hl_combine",
npc_stalker = "hl_combine",
npc_strider = "hl_combine",
npc_turret_ceiling = "hl_combine",
npc_turret_floor = "hl_combine",
npc_turret_ground = "hl_combine",
npc_vortigaunt = "default",
npc_zombie = "hl_zombie",
npc_zombie_torso = "hl_zombie",
npc_zombine = "hl_zombie"
}
local side_relationships = {
default = {
hl_combine = D_HT,
hl_antlion = D_HT,
hl_zombie = D_HT,
hl_infiltrator = D_LI
},
hl_combine = {
default = D_HT,
hl_antlion = D_HT,
hl_zombie = D_HT,
hl_infiltrator = D_LI
},
hl_antlion = {
default = D_HT,
hl_combine = D_HT,
hl_zombie = D_HT,
hl_infiltrator = D_HT
},
hl_zombie = {
default = D_HT,
hl_combine = D_HT,
hl_antlion = D_HT,
hl_infiltrator = D_HT
}
}
local team_map = {}
--AI TEAMS
function setAiTeam(ent, side)
if ent:IsPlayer() and side == "default" then
team_map[ent] = nil
else
team_map[ent] = side
end
for _, npc in pairs(ents.FindByClass("npc_*")) do
if npc == ent or not npc.AddEntityRelationship or not IsValid(npc) then continue end
local otherSide = getAiTeam(npc)
--if otherSide==nil then continue end
if side == otherSide or side == "harmless" then
npc:AddEntityRelationship(ent, D_LI, 99)
elseif side == "wild" then
npc:AddEntityRelationship(ent, D_HT, 99)
else
local relationship = (side_relationships[otherSide] or {})[side]
if relationship then
npc:AddEntityRelationship(ent, relationship, 99)
end
end
if ent:IsNPC() then
if otherSide == side or otherSide == "harmless" then
ent:AddEntityRelationship(npc, D_LI, 99)
elseif side == "wild" then
ent:AddEntityRelationship(npc, D_HT, 99)
else
local relationship = (side_relationships[side] or {})[otherSide]
if relationship then
ent:AddEntityRelationship(npc, relationship, 99)
end
end
end
end
if ent:IsNPC() then
for _, ply in pairs(player.GetAll()) do
local otherSide = getAiTeam(ply)
if otherSide == side or otherSide == "harmless" then
ent:AddEntityRelationship(ply, D_LI, 99)
elseif side == "wild" then
ent:AddEntityRelationship(ply, D_HT, 99)
else
local relationship = (side_relationships[side] or {})[otherSide]
if relationship then
ent:AddEntityRelationship(ply, relationship, 99)
end
end
end
end
if not ent:IsPlayer() and ent:GetTable() then
ent:CallOnRemove("ClearAiTeam", function()
team_map[ent] = nil
end)
end
end
function getAiTeam(ent)
local side
side = team_map[ent]
if side then return side end
side = npc_sides[ent:GetClass()]
if side then return side end
--if ent.formTable then side=ent.formTable.side end
--if side then return side end
if ent:IsPlayer() then return "default" end
return "harmless"
end
hook.Add("OnEntityCreated", "pk_pill_npc_spawn", function(npc)
if npc.AddEntityRelationship then
local otherSide = getAiTeam(npc)
if otherSide == nil then return end
for ent, side in pairs(team_map) do
if not IsValid(ent) then continue end --This really shouldn't happen. But it does. ):
if side == otherSide or side == "harmless" then
npc:AddEntityRelationship(ent, D_LI, 99)
elseif side == "wild" then
npc:AddEntityRelationship(ent, D_HT, 99)
else
local relationship = (side_relationships[otherSide] or {})[side]
if relationship == nil then continue end
npc:AddEntityRelationship(ent, relationship, 99)
end
--TODO CHECK AGAINST ALL NPCS, NOT JUST ONES IN THIS LIST -- THIS MIGHT ACTUALLY BE RIGHT
if ent:IsNPC() then
if otherSide == side or otherSide == "harmless" then
ent:AddEntityRelationship(npc, D_LI, 99)
elseif side == "wild" then
ent:AddEntityRelationship(npc, D_HT, 99)
else
local relationship = (side_relationships[side] or {})[otherSide]
if relationship == nil then continue end
ent:AddEntityRelationship(npc, relationship, 99)
end
end
end
end
end)
hook.Add("PlayerDisconnected", "pk_pill_clearplayerteam", function(ply)
team_map[ply] = nil
end)

View File

@@ -0,0 +1,35 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
--Speed modifications done by tf2 weapons, effects, etc.
hook.Add("SetupMove", "momo_tf2_movemod", function(ply, mv, cmd)
local speedmod = 1
--Check weapons
for _, wep in pairs(ply:GetWeapons()) do
if wep.momo_SpeedMod then
local thismod = wep:momo_SpeedMod()
if thismod then
speedmod = speedmod * thismod
end
end
end
--Change the speed
if speedmod ~= 1 then
local basevel = mv:GetVelocity()
basevel.x = basevel.x * speedmod
basevel.y = basevel.y * speedmod
mv:SetVelocity(basevel)
end
end)

View File

@@ -0,0 +1,132 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
helpers = {}
function helpers.makeList(str, n1, n2)
if not n2 then
n2 = n1
n1 = 1
end
local lst = {}
for i = n1, n2 do
table.insert(lst, string.Replace(str, "#", tostring(i)))
end
return lst
end
common = {}
if SERVER then
function common.shoot(ply, ent, tbl)
local aim = ent.formTable.aim
if ent.formTable.canAim and not ent.formTable.canAim(ply, ent) then return end
if aim.usesSecondaryEnt and not IsValid(ent:GetPillAimEnt()) then return end
local aimEnt = aim.usesSecondaryEnt and ent:GetPillAimEnt() or (ent.formTable.type == "ply" and ent:GetPuppet()) or ent
local start
if aim.attachment then
start = aimEnt:GetAttachment(aimEnt:LookupAttachment(aim.attachment))
elseif aim.offset then
local a = ply:EyeAngles()
a.p = 0
start = {
Pos = ply:EyePos() + a:Forward() * aim.offset,
Ang = ply:EyeAngles()
}
else
return
end
local bullet = {}
-- PLZ FIX
if aim.overrideStart then
bullet.Src = ent:LocalToWorld(aim.overrideStart)
else
if not start then return end
bullet.Src = start.Pos
end
--debugoverlay.Sphere(bullet.Src,10,1, Color(0,0,255), true)
--[[bullet.Src = start.Pos]]
bullet.Attacker = ply
if aim.simple then
bullet.Dir = ply:EyeAngles():Forward()
else
bullet.Dir = start.Ang:Forward()
end
if tbl.spread then
bullet.Spread = Vector(tbl.spread, tbl.spread, 0)
end
bullet.Num = tbl.num
bullet.Damage = tbl.damage
bullet.Force = tbl.force
bullet.Tracer = tbl.tracer and not aim.fixTracers and 1 or 0
if aim.fixTracers then
bullet.Callback = function(_ply, tr, dmg)
local ed = EffectData()
ed:SetStart(tr.StartPos)
ed:SetOrigin(tr.HitPos)
ed:SetScale(5000)
util.Effect(tbl.tracer, ed)
end
else
bullet.TracerName = tbl.tracer
end
--[[bullet.Callback=function(ply,tr,dmg)
if tr.HitPos then
debugoverlay.Sphere(tr.HitPos,50,5, Color(0,255,0), true)
end
end]]
aimEnt:FireBullets(bullet)
--Animation
if tbl.anim then
ent:PillAnim(tbl.anim, true)
end
--Sound
ent:PillSound("shoot", true)
end
function common.melee(ply, ent, tbl)
if not ply:IsOnGround() then return end
if tbl.animCount then
ent:PillAnim("melee" .. math.random(tbl.animCount), true)
else
ent:PillAnim("melee", true)
end
ent:PillGesture("melee")
ent:PillSound("melee")
timer.Simple(tbl.delay, function()
if not IsValid(ent) then return end
if ply:TraceHullAttack(ply:EyePos(), ply:EyePos() + ply:EyeAngles():Forward() * tbl.range, Vector(-10, -10, -10), Vector(10, 10, 10), tbl.dmg, DMG_SLASH, 1, true) then
ent:PillSound("melee_hit")
else
ent:PillSound("melee_miss")
end
end)
end
end

View File

@@ -0,0 +1,201 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
AddCSLuaFile()
local voxPacks = {}
function registerVox(name, tbl)
voxPacks[name] = tbl
end
if CLIENT then
concommand.Add("pk_pill_voxmenu", function(ply, cmd, args, str)
if pk_pills.getMappedEnt(ply) and pk_pills.getMappedEnt(ply).formTable.voxSet then
local voiceMenuSrc = [[
<head>
<style>
body {-webkit-user-select: none; font-family: Arial;}
h1 {margin: 10px 0; background-color: #CCF; border: 1px solid #00A; color: #00A; width: 150px; font-style:italic;}
.close {background: red; border: 2px solid black; float: right;}
.close:hover {background: #F44;}
#input {height: 55px; background: white; border: 1px solid gray; overflow-x: auto; white-space: nowrap; font-size: 30px;}
#picker {background: #CCC; border: 1px solid black; margin-top: 10px; overflow-y: auto; position: relative;}
#picker>div {margin: 4px;cursor: pointer;}
#cursor {display: inline-block; width: 0; height: 26px; border-left: 2px solid black; margin-top: 2px;}
#picker>div:hover {background-color: #FFC; border: 1px solid #AA0;}
#selected {background-color: #CCF; border: 1px solid #00A;}
.highlight {color: red; font-weight: bold;}
</style>
</head>
<body>
<button class="close" onclick="console.log('RUNLUA:SELF:Remove()')">X</button>
<h1>PillVox</h1>
<div id="input"></div>
<div id="picker"></div>
</body>
<script>
var picker = document.getElementById('picker')
var input = document.getElementById('input')
picker.style.height= (window.innerHeight-150)+"px"
var phrases = []
var txt=""
var cPos=0
function htmlSafe(str) {
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/ /g,'&nbsp;')
}
function render(renderpicker) {
//search
var begin = txt.substr(0,cPos)
var end = txt.substr(cPos)
input.innerHTML=htmlSafe(begin)+"<div id='cursor'></div>"+htmlSafe(end)
input.scrollLeft = input.scrollWidth
//picker
if (renderpicker) {
var out=[]
if (txt=="") {
for (var i in phrases) {
out.push("<div data-phrase='"+phrases[i]+"' onclick='pick(this)'>"+phrases[i]+"</div>")
}
} else {
var tosort=[]
for (var i in phrases) {
var phrase = phrases[i]
var fragments = txt.trim().split(' ')
var score=0
var highlighted = phrase.replace(new RegExp(fragments.join("|"),"gi"), function(matched) {
score+=matched.length
return "<span class='highlight'>"+matched+"</span>"
})
score+=1/phrase.length
if (highlighted!=phrase) {
tosort.push({html: ("<div data-phrase='"+phrase.replace(/'/g,"&#39;")+"' onclick='pick(this)'>"+highlighted+"</div>"), score: score})
}
}
tosort.sort(function(a,b) {return b.score-a.score})
for (j in tosort) {
out.push(tosort[j].html)
}
}
picker.innerHTML=out.join('')
var selectedElement = picker.childNodes[0]
if (selectedElement) {
selectedElement.setAttribute("id","selected")
selected = selectedElement.dataset.phrase
}
}
}
function pick(e) {
console.log('RUNLUA:RunConsoleCommand("pk_pill_vox","'+e.dataset.phrase+'")')
console.log('RUNLUA:SELF:Remove()')
}
function init(t) {
for (k in t) {
phrases.push(k)
}
phrases.sort()
render(true)
}
//cursor
setInterval(function() {
var cursor = document.getElementById('cursor')
if (cursor.style.visibility=='visible')
cursor.style.visibility='hidden'
else
cursor.style.visibility='visible'
},400)
document.addEventListener('keydown', function(event) {
var key = event.keyCode
if (key>=65 && key<=90) {
txt=txt.substr(0,cPos)+String.fromCharCode(key+32)+txt.substr(cPos)
cPos++
render(true)
} else if (key>=48 && key<=57 || key==32) {
txt=txt.substr(0,cPos)+String.fromCharCode(key)+txt.substr(cPos)
cPos++
render(true)
} else if (key==8) {
if (cPos>0) {
txt=txt.substr(0,cPos-1)+txt.substr(cPos)
cPos--
}
render(true)
} else if (key==13) {
var selectedElement = document.getElementById('selected')
if (selectedElement) {
pick(selectedElement)
} else {
console.log('RUNLUA:SELF:Remove()')
}
render()
} else if (key==37) {
if (cPos>0) {
cPos--
}
render()
} else if (key==39) {
if (cPos<txt.length) {
cPos++
}
render()
} else if (key==38) {
var selectedElement = document.getElementById('selected')
if (selectedElement.previousSibling) {
selectedElement.removeAttribute('id')
selectedElement=selectedElement.previousSibling
selectedElement.setAttribute("id","selected")
picker.scrollTop = selectedElement.offsetTop-225
}
} else if (key==40) {
var selectedElement = document.getElementById('selected')
if (selectedElement.nextSibling) {
selectedElement.removeAttribute('id')
selectedElement=selectedElement.nextSibling
selectedElement.setAttribute("id","selected")
picker.scrollTop = selectedElement.offsetTop-225
}
}
})
</script>
]]
local html = vgui.Create("DHTML", panel)
html:SetPos(10, ScrH() / 6)
html:SetSize(300, ScrH() * (2 / 3))
html:SetAllowLua(true)
html:SetHTML(voiceMenuSrc)
html:RunJavascript("init(" .. util.TableToJSON(voxPacks[pk_pills.getMappedEnt(ply).formTable.voxSet]) .. ")")
html:MakePopup()
end
end)
else
concommand.Add("pk_pill_vox", function(ply, cmd, args, str)
if pk_pills.getMappedEnt(ply) and pk_pills.getMappedEnt(ply).formTable.voxSet then
pk_pills.getMappedEnt(ply):EmitSound(voxPacks[pk_pills.getMappedEnt(ply).formTable.voxSet][args[1]])
end
end)
end