Initial commit

This commit is contained in:
2026-03-15 14:54:49 +03:00
commit 64f8029c06
4027 changed files with 254888 additions and 0 deletions

533
lua/autorun/base_npcs.lua Normal file
View File

@@ -0,0 +1,533 @@
-- Don't try to edit this file if you're trying to add new NPCs.
-- Just make a new file and copy the format below.
local function AddNPC( t, class )
if ( !t.Name ) then t.Name = "#" .. ( class or t.Class ) end
t.Author = "VALVe"
list.Set( "NPC", class or t.Class, t )
end
local Category = "#spawnmenu.category.humans_resistance"
AddNPC( {
Class = "npc_alyx",
Category = Category,
Weapons = { "weapon_alyxgun", "weapon_smg1", "weapon_shotgun" },
KeyValues = { SquadName = "resistance" }
} )
AddNPC( {
Class = "npc_barney",
Category = Category,
Weapons = { "weapon_smg1", "weapon_shotgun", "weapon_ar2" },
KeyValues = { SquadName = "resistance" }
} )
AddNPC( {
Class = "npc_breen",
Category = Category,
SpawnFlags = 131072, -- SF_BREEN_GMOD_SPAWNMENU, makes him be a combine for NPC relationships
Weapons = { "" }
} )
AddNPC( {
Class = "npc_dog",
Category = Category
} )
AddNPC( {
Class = "npc_eli",
Category = Category,
Weapons = { "" }
} )
AddNPC( {
Class = "npc_gman",
Category = Category
} )
-- Did you know that this MAN can shoot annabelle like he's been doing it his whole life?
AddNPC( {
Class = "npc_kleiner",
Category = Category,
Weapons = { "" }
} )
AddNPC( {
Class = "npc_mossman",
Category = Category,
Weapons = { "" }
} )
-- I don't trust these Vorts, but I'll let em stay in this category until they mess up
AddNPC( {
Class = "npc_vortigaunt",
Category = Category,
KeyValues = { SquadName = "resistance" }
} )
AddNPC( {
Name = "#npc_vortigaunt_slave",
Class = "npc_vortigaunt",
Category = Category,
Model = "models/vortigaunt_slave.mdl"
}, "VortigauntSlave" )
AddNPC( {
Class = "npc_citizen",
Category = Category,
KeyValues = { citizentype = CT_DOWNTRODDEN, SquadName = "resistance" },
Weapons = { "" } -- Tells the spawnmenu that this NPC can use weapons, but doesn't have any default ones
} )
AddNPC( {
Name = "#npc_citizen_rebel",
Class = "npc_citizen",
Category = Category,
SpawnFlags = SF_CITIZEN_RANDOM_HEAD,
KeyValues = { citizentype = CT_REBEL, SquadName = "resistance" },
Weapons = { "weapon_pistol", "weapon_smg1", "weapon_ar2", "weapon_shotgun", "weapon_rpg" }
}, "Rebel" )
AddNPC( {
Class = "npc_citizen",
Category = Category,
Model = "models/odessa.mdl",
KeyValues = { citizentype = CT_UNIQUE, SquadName = "resistance" },
Weapons = { "" }
}, "npc_odessa" )
AddNPC( {
Name = "#npc_citizen_medic",
Class = "npc_citizen",
Category = Category,
SpawnFlags = SERVER and bit.bor( SF_NPC_DROP_HEALTHKIT, SF_CITIZEN_MEDIC ) or nil,
KeyValues = { citizentype = CT_REBEL, SquadName = "resistance" },
Weapons = { "weapon_pistol", "weapon_smg1", "weapon_ar2" }
}, "Medic" )
AddNPC( {
Name = "#npc_citizen_refugee",
Class = "npc_citizen",
Category = Category,
KeyValues = { citizentype = CT_REFUGEE, SquadName = "resistance" },
Weapons = { "weapon_pistol", "weapon_smg1" }
}, "Refugee" )
AddNPC( {
Name = "#npc_vortigaunt_uriah",
Class = "npc_vortigaunt",
Category = Category,
Model = "models/vortigaunt_doctor.mdl",
KeyValues = { SquadName = "resistance" }
}, "VortigauntUriah" )
AddNPC( {
Class = "npc_magnusson",
Category = Category,
Weapons = { "" }
} )
if ( IsMounted( "lostcoast" ) ) then
AddNPC( {
Class = "npc_fisherman",
Category = Category,
Weapons = { "weapon_oldmanharpoon" }
} ) -- Has no death sequence/ragdoll
end
AddNPC( {
Class = "npc_turret_floor",
Category = Category,
OnFloor = true,
TotalSpawnFlags = SF_FLOOR_TURRET_CITIZEN,
Rotate = Angle( 0, 180, 0 ),
Offset = 2,
KeyValues = { SquadName = "resistance" }
}, "npc_turret_floor_resistance" )
AddNPC( {
Class = "npc_rollermine",
Category = Category,
Offset = 20,
KeyValues = { SquadName = "resistance" },
SpawnFlags = 262144, -- SF_ROLLERMINE_HACKED
NoDrop = true
}, "npc_rollermine_hacked" )
Category = "#spawnmenu.category.zombies_aliens"
AddNPC( {
Class = "npc_zombie",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_zombie_torso",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_poisonzombie",
Category = Category,
KeyValues = { SquadName = "poison" }
} )
AddNPC( {
Class = "npc_antlion",
Category = Category,
KeyValues = { SquadName = "antlions" }
} )
AddNPC( {
Class = "npc_antlionguard",
Category = Category,
KeyValues = { SquadName = "antlions" }
} )
AddNPC( {
Class = "npc_barnacle",
Category = Category,
OnCeiling = true,
Offset = 2
} )
AddNPC( {
Class = "npc_fastzombie",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_headcrab",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_headcrab_black",
Category = Category,
KeyValues = { SquadName = "poison" }
} )
AddNPC( {
Class = "npc_headcrab_fast",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_fastzombie_torso",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_zombine",
Category = Category,
KeyValues = { SquadName = "zombies" }
} )
AddNPC( {
Class = "npc_antlionguard",
Category = Category,
KeyValues = { cavernbreed = 1, incavern = 1, SquadName = "antlions" },
Material = "Models/antlion_guard/antlionGuard2"
}, "npc_antlionguardian" )
AddNPC( {
Class = "npc_antlion_grub",
Category = Category,
NoDrop = true,
Offset = 1
} )
AddNPC( {
Class = "npc_antlion_worker",
Category = Category,
KeyValues = { SquadName = "antlions" }
} )
Category = "#spawnmenu.category.animals"
AddNPC( {
Class = "npc_monk",
Category = Category,
Weapons = { "weapon_annabelle" }
} )
AddNPC( {
Class = "npc_crow",
Category = Category,
NoDrop = true
} )
AddNPC( {
Class = "npc_pigeon",
Category = Category,
NoDrop = true
} )
AddNPC( {
Class = "npc_seagull",
Category = Category,
NoDrop = true
} )
Category = "#spawnmenu.category.combine"
AddNPC( {
Class = "npc_metropolice",
Category = Category,
Weapons = { "weapon_stunstick", "weapon_pistol", "weapon_smg1" },
SpawnFlags = SF_NPC_DROP_HEALTHKIT,
KeyValues = { SquadName = "overwatch" }
} )
AddNPC( {
Class = "npc_rollermine",
Category = Category,
Offset = 20,
KeyValues = { SquadName = "overwatch" },
NoDrop = true
} )
-- It is still considered an enemy by friendly NPCs (so that it chases them)
AddNPC( {
Class = "npc_rollermine",
Category = Category,
Offset = 20,
KeyValues = { SquadName = "overwatch" },
SpawnFlags = 65536, -- SF_ROLLERMINE_FRIENDLY
NoDrop = true
}, "npc_rollermine_friendly" )
AddNPC( {
Class = "npc_turret_floor",
Category = Category,
OnFloor = true,
TotalSpawnFlags = 0,
Rotate = Angle( 0, 180, 0 ),
Offset = 2,
KeyValues = { SquadName = "overwatch" }
} )
AddNPC( {
Class = "npc_combine_s",
Category = Category,
Model = "models/combine_soldier.mdl",
Skin = 0,
Weapons = { "weapon_smg1", "weapon_ar2" },
KeyValues = { SquadName = "overwatch", Numgrenades = 5 }
} )
AddNPC( {
Name = "#npc_combine_s_shotgun",
Class = "npc_combine_s",
Category = Category,
Model = "models/combine_soldier.mdl",
Skin = 1,
Weapons = { "weapon_shotgun" },
KeyValues = { SquadName = "overwatch", Numgrenades = 5 }
}, "ShotgunSoldier" )
AddNPC( {
Name = "#npc_combine_s_prison",
Class = "npc_combine_s",
Category = Category,
Model = "models/combine_soldier_prisonguard.mdl",
Skin = 0,
Weapons = { "weapon_smg1", "weapon_ar2" },
KeyValues = { SquadName = "novaprospekt", Numgrenades = 5 }
}, "CombinePrison" )
AddNPC( {
Name = "#npc_combine_s_prison_shotgun",
Class = "npc_combine_s",
Category = Category,
Model = "models/combine_soldier_prisonguard.mdl",
Skin = 1,
Weapons = { "weapon_shotgun" },
KeyValues = { SquadName = "novaprospekt", Numgrenades = 5 }
}, "PrisonShotgunner" )
AddNPC( {
Name = "#npc_combine_s_elite",
Class = "npc_combine_s",
Category = Category,
Model = "models/combine_super_soldier.mdl",
Skin = 0,
Weapons = { "weapon_ar2" },
KeyValues = { Numgrenades = 10, SquadName = "overwatch" },
SpawnFlags = SF_NPC_NO_PLAYER_PUSHAWAY
}, "CombineElite" )
AddNPC( {
Class = "npc_cscanner",
Category = Category,
Offset = 20,
KeyValues = { SquadName = "overwatch", SpotlightLength = 500, SpotlightWidth = 100 },
NoDrop = true
} )
AddNPC( {
Class = "npc_clawscanner",
Category = Category,
Offset = 20,
KeyValues = { SquadName = "overwatch", SpotlightLength = 500, SpotlightWidth = 100 },
NoDrop = true
} )
AddNPC( {
Class = "npc_combinegunship",
Category = Category,
Offset = 300,
KeyValues = { SquadName = "overwatch" },
NoDrop = true
} )
AddNPC( {
Class = "npc_combinedropship",
Category = Category,
Offset = 300,
KeyValues = { SquadName = "overwatch" },
NoDrop = true
} )
AddNPC( {
Class = "npc_helicopter",
Category = Category,
Offset = 300,
Health = 600,
KeyValues = { SquadName = "overwatch" },
NoDrop = true
} )
AddNPC( {
Class = "npc_combine_camera",
Category = Category,
OnCeiling = true,
Offset = 2,
KeyValues = { SquadName = "overwatch" },
NoDrop = true
} )
AddNPC( {
Class = "npc_turret_ceiling",
Category = Category,
SpawnFlags = 32, -- SF_NPC_TURRET_AUTOACTIVATE
OnCeiling = true,
Offset = 0,
KeyValues = { SquadName = "overwatch" }
} )
AddNPC( {
Class = "npc_strider",
Category = Category,
Offset = 100,
KeyValues = { SquadName = "overwatch" }
} )
AddNPC( {
Class = "npc_stalker",
Category = Category,
KeyValues = { SquadName = "npc_stalker_squad" },
Offset = 10
} )
AddNPC( {
Class = "npc_manhack",
Category = Category,
KeyValues = { SquadName = "overwatch" },
NoDrop = true
} )
-- This is meant for NPC reskins, so humanoid NPC reskins don't sound like combine.
-- This is also just for fun, and exists here to let people know that the option exists and how to use it.
AddNPC( {
Class = "npc_citizen",
Category = Category,
KeyValues = { citizentype = CT_REBEL, SquadName = "overwatch", Hostile = "1" },
Weapons = { "weapon_pistol", "weapon_smg1", "weapon_ar2", "weapon_shotgun", "weapon_rpg" }
}, "npc_citizen_rebel_enemy" )
AddNPC( {
Class = "npc_hunter",
Category = Category,
KeyValues = { SquadName = "overwatch" }
} )
if ( IsMounted( "hl1" ) or IsMounted( "hl1mp" ) ) then
Category = "Half-Life: Source"
AddNPC( { Class = "monster_alien_grunt", Category = Category } )
AddNPC( { Class = "monster_nihilanth", Category = Category, Offset = 1200, SpawnFlags = 262144, NoDrop = true } )
AddNPC( { Class = "monster_tentacle", Category = Category } )
AddNPC( { Class = "monster_alien_slave", Category = Category } )
AddNPC( { Class = "monster_bigmomma", Category = Category } )
AddNPC( { Class = "monster_bullchicken", Category = Category } )
AddNPC( { Class = "monster_gargantua", Category = Category } )
AddNPC( { Class = "monster_human_assassin", Category = Category } )
AddNPC( { Class = "monster_babycrab", Category = Category } )
AddNPC( { Class = "monster_human_grunt", Category = Category } )
AddNPC( { Class = "monster_cockroach", Category = Category } )
AddNPC( { Class = "monster_houndeye", Category = Category } )
AddNPC( { Class = "monster_scientist", Category = Category, KeyValues = { body = "-1" } } )
AddNPC( { Class = "monster_snark", Category = Category, Offset = 6, NoDrop = true } )
AddNPC( { Class = "monster_zombie", Category = Category } )
AddNPC( { Class = "monster_headcrab", Category = Category } )
AddNPC( { Class = "monster_alien_controller", Category = Category, NoDrop = true } )
AddNPC( { Class = "monster_barney", Category = Category } )
-- Hack to have it not invert angles again
local turretOnDupe = function( npc, data ) npc:SetKeyValue( "spawnflags", bit.bor( npc.SpawnFlags, 2048 ) ) end
local turretOnCeiling = function( npc ) npc:SetKeyValue( "orientation", 1 ) end
AddNPC( { Class = "monster_turret", Category = Category, Offset = 0, OnCeiling = turretOnCeiling, OnFloor = true, SpawnFlags = 32, OnDuplicated = turretOnDupe } )
AddNPC( { Class = "monster_miniturret", Category = Category, Offset = 0, OnCeiling = turretOnCeiling, OnFloor = true, SpawnFlags = 32, OnDuplicated = turretOnDupe } )
AddNPC( { Class = "monster_sentry", Category = Category, Offset = 0, OnFloor = true, SpawnFlags = 32 } )
end
if ( IsMounted( "portal" ) ) then
Category = "Portal"
AddNPC( {
Class = "npc_portal_turret_floor",
Category = Category,
OnFloor = true,
Rotate = Angle( 0, 180, 0 ),
Offset = 2,
TotalSpawnFlags = 0,
} )
AddNPC( {
Class = "npc_rocket_turret",
Category = Category,
OnFloor = true,
SpawnFlags = 2, --SF_ROCKET_TURRET_SPAWNMENU, makes it target NPCs
Offset = 0,
Rotate = Angle( 0, 180, 0 ),
} )
AddNPC( {
Class = "npc_security_camera",
Category = Category,
Offset = -1,
SpawnFlags = 32, --SF_SECURITY_CAMERA_AUTOACTIVATE
SnapToNormal = true,
NoDrop = true
} )
end

View File

@@ -0,0 +1,269 @@
-- Don't try to edit this file if you're trying to add new vehicles
-- Just make a new file and copy the format below.
local function AddVehicle( t, class )
list.Set( "Vehicles", class, t )
end
local Category = "Half-Life 2"
AddVehicle( {
-- Required information
Name = "#spawnmenu.vehicle.jeep",
Model = "models/buggy.mdl",
Class = "prop_vehicle_jeep_old",
Category = Category,
-- Optional information
Author = "VALVe",
Information = "The regular old jeep",
KeyValues = {
vehiclescript = "scripts/vehicles/jeep_test.txt"
}
}, "Jeep" )
AddVehicle( {
Name = "#spawnmenu.vehicle.airboat",
Model = "models/airboat.mdl",
Class = "prop_vehicle_airboat",
Category = Category,
Author = "VALVe",
Information = "Airboat from Half-Life 2",
KeyValues = {
vehiclescript = "scripts/vehicles/airboat.txt"
}
}, "Airboat" )
AddVehicle( {
Name = "#spawnmenu.vehicle.prisoner_pod",
Model = "models/vehicles/prisoner_pod_inner.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "The prisoner pod",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
}
}, "Pod" )
AddVehicle( {
Name = "#spawnmenu.vehicle.jalopy",
Model = "models/vehicle.mdl",
Class = "prop_vehicle_jeep",
Category = Category,
Author = "VALVe",
Information = "The muscle car from Episode 2",
KeyValues = {
vehiclescript = "scripts/vehicles/jalopy.txt"
}
}, "Jalopy" )
Category = "#spawnmenu.category.chairs"
local function HandleRollercoasterAnimation( vehicle, player )
return player:SelectWeightedSequence( ACT_GMOD_SIT_ROLLERCOASTER )
end
AddVehicle( {
Name = "#spawnmenu.chair.wooden",
Model = "models/nova/chair_wood01.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A wooden chair",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Chair_Wood" )
AddVehicle( {
Name = "#spawnmenu.chair.plastic",
Model = "models/nova/chair_plastic01.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A plastic chair",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Chair_Plastic" )
AddVehicle( {
Name = "#spawnmenu.chair.office",
Model = "models/nova/chair_office01.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A small office chair",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Chair_Office1" )
AddVehicle( {
Name = "#spawnmenu.chair.office_big",
Model = "models/nova/chair_office02.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A big office chair",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Chair_Office2" )
AddVehicle( {
Name = "#spawnmenu.seat.jeep",
Model = "models/nova/jeep_seat.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A seat from VALVe's Jeep",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Seat_Jeep" )
AddVehicle( {
Name = "#spawnmenu.seat.airboat",
Model = "models/nova/airboat_seat.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A seat from VALVe's Airboat",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Seat_Airboat" )
AddVehicle( {
Name = "#spawnmenu.seat.jalopy",
Model = "models/nova/jalopy_seat.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "VALVe",
Information = "A seat from VALVe's Jalopy",
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandleRollercoasterAnimation,
}
}, "Seat_Jalopy" )
-- PhoeniX-Storms Vehicles
local function HandlePHXSeatAnimation( vehicle, player )
return player:SelectWeightedSequence( ACT_HL2MP_SIT )
end
local function HandlePHXVehicleAnimation( vehicle, ply )
return ply:SelectWeightedSequence( ACT_DRIVE_JEEP )
end
local function HandlePHXAirboatAnimation( vehicle, ply )
return ply:SelectWeightedSequence( ACT_DRIVE_AIRBOAT )
end
AddVehicle( {
Name = "#spawnmenu.seat.simple_sit",
Model = "models/props_phx/carseat2.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "PhoeniX-Storms",
Information = "PHX Airboat Seat with Sitting Animation",
Offset = 16,
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandlePHXSeatAnimation,
}
}, "phx_seat" )
AddVehicle( {
Name = "#spawnmenu.seat.simple_jeep",
Model = "models/props_phx/carseat3.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "PhoeniX-Storms",
Information = "PHX Airboat Seat with Jeep animations",
Offset = 16,
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandlePHXVehicleAnimation,
}
}, "phx_seat2" )
AddVehicle( {
Name = "#spawnmenu.seat.simple_airboat",
Model = "models/props_phx/carseat2.mdl",
Class = "prop_vehicle_prisoner_pod",
Category = Category,
Author = "PhoeniX-Storms",
Information = "PHX Airboat Seat with Airboat animations",
Offset = 16,
KeyValues = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
Members = {
HandleAnimation = HandlePHXAirboatAnimation,
}
}, "phx_seat3" )

View File

@@ -0,0 +1,121 @@
if ( !engine.IsPlayingDemo() ) then return end
local VideoSettings = engine.VideoSettings()
if ( !VideoSettings ) then return end
PrintTable( VideoSettings )
local SmoothedAng = nil
local SmoothedFOV = nil
local SmoothedPos = nil
local AutoFocusPoint = nil
hook.Add( "Initialize", "DemoRenderInit", function()
if ( VideoSettings.frameblend < 2 ) then
RunConsoleCommand( "pp_fb", "0" )
else
RunConsoleCommand( "pp_fb", "1" )
RunConsoleCommand( "pp_fb_frames", VideoSettings.frameblend )
RunConsoleCommand( "pp_fb_shutter", VideoSettings.fbshutter )
end
end )
hook.Add( "RenderScene", "RenderForDemo", function( ViewOrigin, ViewAngles, ViewFOV )
if ( !engine.IsPlayingDemo() ) then return false end
render.Clear( 0, 0, 0, 255, true, true )
local FramesPerFrame = 1
if ( frame_blend.IsActive() ) then
FramesPerFrame = frame_blend.RenderableFrames()
frame_blend.AddFrame()
if ( frame_blend.ShouldSkipFrame() ) then
frame_blend.DrawPreview()
return true
end
end
if ( !SmoothedAng ) then SmoothedAng = ViewAngles * 1 end
if ( !SmoothedFOV ) then SmoothedFOV = ViewFOV end
if ( !SmoothedPos ) then SmoothedPos = ViewOrigin * 1 end
if ( !AutoFocusPoint ) then AutoFocusPoint = SmoothedPos * 1 end
if ( VideoSettings.viewsmooth > 0 ) then
SmoothedAng = LerpAngle( ( 1 - VideoSettings.viewsmooth ) / FramesPerFrame, SmoothedAng, ViewAngles )
SmoothedFOV = Lerp( ( 1 - VideoSettings.viewsmooth ) / FramesPerFrame, SmoothedFOV, ViewFOV )
else
SmoothedAng = ViewAngles * 1
SmoothedFOV = ViewFOV
end
if ( VideoSettings.possmooth > 0 ) then
SmoothedPos = LerpVector( ( 1 - VideoSettings.possmooth ) / FramesPerFrame, SmoothedPos, ViewOrigin )
else
SmoothedPos = ViewOrigin * 1
end
local view = {
x = 0,
y = 0,
w = math.Round( VideoSettings.width ),
h = math.Round( VideoSettings.height ),
angles = SmoothedAng,
origin = SmoothedPos,
fov = SmoothedFOV,
drawhud = false,
drawviewmodel = true,
dopostprocess = true,
drawmonitors = true
}
if ( VideoSettings.dofsteps && VideoSettings.dofpasses ) then
local trace = util.TraceHull( {
start = view.origin,
endpos = view.origin + ( view.angles:Forward() * 8000 ),
mins = Vector( -2, -2, -2 ),
maxs = Vector( 2, 2, 2 ),
filter = { GetViewEntity() }
} )
local focuspeed = math.Clamp( ( VideoSettings.doffocusspeed / FramesPerFrame ) * 0.2, 0, 1 )
AutoFocusPoint = LerpVector( focuspeed, AutoFocusPoint, trace.HitPos )
local UsableFocusPoint = view.origin + view.angles:Forward() * AutoFocusPoint:Distance( view.origin )
RenderDoF( view.origin, view.angles, UsableFocusPoint, VideoSettings.dofsize * 0.3, VideoSettings.dofsteps, VideoSettings.dofpasses, false, table.Copy( view ) )
else
render.RenderView( view )
end
-- TODO: IF RENDER HUD
render.RenderHUD( 0, 0, view.w, view.h )
local ShouldRecordThisFrme = frame_blend.IsLastFrame()
if ( frame_blend.IsActive() ) then
frame_blend.BlendFrame()
frame_blend.DrawPreview()
end
if ( ShouldRecordThisFrme ) then
menu.RecordFrame()
end
return true
end )

View File

@@ -0,0 +1,30 @@
concommand.Add( "gm_demo", function( ply, cmd, arg )
if ( engine.IsRecordingDemo() ) then
RunConsoleCommand( "stop" )
return
end
local dynamic_name = game.GetMap() .. " " .. util.DateStamp()
RunConsoleCommand( "record", "demos/" .. dynamic_name .. ".dem" )
RunConsoleCommand( "record_screenshot", dynamic_name )
end, nil, "Start or stop recording a demo.", FCVAR_DONTRECORD )
local matRecording = nil
local drawicon = CreateConVar( "gm_demo_icon", 1, FCVAR_ARCHIVE + FCVAR_DONTRECORD, "If set to 1, display a 'RECORDING' icon during gm_demo." )
hook.Add( "HUDPaint", "DrawRecordingIcon", function()
if ( !engine.IsRecordingDemo() || !drawicon:GetBool() ) then return end
if ( !matRecording ) then
matRecording = Material( "gmod/recording.png" )
end
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( matRecording )
surface.DrawTexturedRect( ScrW() - 512, 0, 512, 256 )
end )

View File

@@ -0,0 +1,159 @@
-- Makes stuff easier to parse visually
local offColor = Color( 220, 220, 220 )
local function FindInTable( tab, find, parents, depth )
depth = depth or 0
parents = parents or ""
if ( !istable( tab ) ) then return end
if ( depth > 3 ) then return end
depth = depth + 1
for k, v in pairs ( tab ) do
if ( isstring( k ) ) then
if ( k and k:lower():find( find:lower() ) ) then
local info = isfunction( v ) and debug.getinfo( v ) or { source = "" }
if ( info.source:len() != 0 ) then info.source = " " .. info.source end
Msg( " ", parents, k, string.rep( " ", math.Clamp( 32 - ( parents:len() + k:len() ), 1, 32 ) ) )
MsgC( offColor, "(", type( v ), " - ", v, info.source, ")\n" )
end
-- Recurse
if ( istable( v ) and
k != "_R" and
k != "_E" and
k != "_G" and
k != "_M" and
k != "_LOADED" and
k != "__index" ) then
local NewParents = parents .. k .. "."
FindInTable( v, find, NewParents, depth )
end
end
end
end
local function FindInHooks( base, name )
for b, t in pairs( hook.GetTable() ) do
local head = true
if ( istable( t ) and b:lower():find( base:lower() ) ) then
for n, f in pairs( t ) do
local nameStr = tostring( n )
if ( !name or nameStr:lower():find( tostring( name ):lower() ) ) then
if ( head ) then Msg( "\n ", b, " hooks:\n" ) head = false end
local info = isfunction( f ) and debug.getinfo( f, "S" ) or { source = "" }
if ( info.source:len() != 0 ) then info.source = " " .. info.source end
Msg( "\t", nameStr, string.rep( " ", math.Clamp( 32 - nameStr:len(), 1, 32 ) ) )
MsgC( offColor, "(", tostring( f ), info.source, ")\n" )
end
end
end
end
end
local function UTIL_IsCommandIssuedByServerAdmin( ply )
if ( game.SinglePlayer() ) then return true end -- Singleplayer
if ( !IsValid( ply ) ) then return SERVER end -- Dedicated server console
return ply:IsListenServerHost() -- Only if we are a listen server host
end
--[[---------------------------------------------------------
Name: Find
-----------------------------------------------------------]]
local function Find( ply, command, arguments )
if ( !UTIL_IsCommandIssuedByServerAdmin( ply ) ) then return end
if ( !arguments[1] ) then
if ( command:StartsWith( "lua_findhooks" ) ) then
MsgN( "Usage: lua_findhooks <event name> [hook identifier]" )
return
end
MsgN( "Usage: lua_find <text>" )
return
end
if ( command:StartsWith( "lua_findhooks" ) ) then
Msg( "Finding '", arguments[1], "' hooks ",
( arguments[2] and "with name '" .. arguments[2] .. "' " or "" ),
( SERVER and "SERVERSIDE" or "CLIENTSIDE" ), ":\n"
)
FindInHooks( arguments[1], arguments[2] )
else
Msg( "Finding '", arguments[1], "' ", ( SERVER and "SERVERSIDE" or "CLIENTSIDE" ), ":\n" )
FindInTable( _G, arguments[1] )
--FindInTable( debug.getregistry(), arguments[1] )
end
Msg( "\n" )
if ( SERVER and IsValid( ply ) and ply:IsPlayer() and ply:IsListenServerHost() ) then
RunConsoleCommand( command .. "_cl", arguments[1], arguments[2] )
end
end
if ( SERVER ) then
concommand.Add( "lua_find", Find, nil, "Find any variable by name on the server.", FCVAR_DONTRECORD )
concommand.Add( "lua_findhooks", Find, nil, "Find hooks by event name and hook identifier on the server.", FCVAR_DONTRECORD )
else
concommand.Add( "lua_find_cl", Find, nil, "Find any variable by name on the client.", FCVAR_DONTRECORD )
concommand.Add( "lua_findhooks_cl", Find, nil, "Find hooks by event name and hook identifier on the client.", FCVAR_DONTRECORD )
end
if ( SERVER ) then
--[[---------------------------------------------------------
What am I looking at?
-----------------------------------------------------------]]
concommand.Add( "trace", function( ply )
if ( !IsValid( ply ) || ( !game.SinglePlayer() && !ply:IsListenServerHost() ) ) then return end
local tr = util.TraceLine( {
start = ply:EyePos(),
endpos = ply:EyePos() + ply:GetAimVector() * 30000,
filter = ply,
//mask = MASK_OPAQUE_AND_NPCS,
} )
PrintTable( tr )
print( "Dist: ", ( tr.HitPos - tr.StartPos ):Length() )
if ( IsValid( tr.Entity ) ) then print( "Model: " .. tr.Entity:GetModel() ) end
-- Print out the clientside class name
ply:SendLua( [[print(Entity(]] .. ply:EntIndex() .. [[):GetEyeTrace().Entity)]] )
end )
end

209
lua/autorun/game_hl2.lua Normal file
View File

@@ -0,0 +1,209 @@
local Category = ""
-- This is basically dupliacator.GenericDuplicatorFunction, but calls the relevant hooks
-- Move this all to commands.lua?
local function ADD_ITEM_DUPEFUNC( ply, data )
if ( IsValid( ply ) && !gamemode.Call( "PlayerSpawnSENT", ply, data.Class ) ) then return NULL end
local ent = ents.Create( data.Class )
if ( !IsValid( ent ) ) then return NULL end -- Must've hit edict limit
-- Remove certain fields we do not want dupes to manipulate
data.Model = nil
-- Restore the keyvalues
local entTable = list.GetEntry( "SpawnableEntities", data.EntityName )
if ( entTable && entTable.ClassName == data.Class && entTable.KeyValues ) then
for k, v in pairs( entTable.KeyValues ) do
ent:SetKeyValue( k, v )
end
end
duplicator.DoGeneric( ent, data )
ent:Spawn()
--duplicator.DoGenericPhysics( ent, ply, data )
ent:Activate()
ent.EntityName = data.EntityName
-- For hacked combine mines, they reset their skin
if ( data.Skin ) then ent:SetSkin( data.Skin ) end
if ( IsValid( ply ) ) then
ent:SetCreator( ply )
gamemode.Call( "PlayerSpawnedSENT", ply, ent )
end
return ent
end
local function ADD_WEAPON_DUPEFUNC( ply, data )
if ( IsValid( ply ) && !gamemode.Call( "PlayerSpawnSWEP", ply, data.Class, list.GetEntry( "Weapon", data.Class ) ) ) then return NULL end
local ent = ents.Create( data.Class )
if ( !IsValid( ent ) ) then return NULL end -- Must've hit edict limit
-- Remove certain fields we do not want dupes to manipulate
data.Model = nil
duplicator.DoGeneric( ent, data )
ent:Spawn()
--duplicator.DoGenericPhysics( ent, ply, data )
ent:Activate()
ent.EntityName = data.EntityName
if ( IsValid( ply ) ) then
ent:SetCreator( ply )
gamemode.Call( "PlayerSpawnedSWEP", ply, ent )
end
return ent
end
local function ADD_ITEM( class, offset, extras, classOverride )
local base = { PrintName = "#" .. ( classOverride or class ), ClassName = class, Category = Category, NormalOffset = offset or 32, DropToFloor = true, Author = "VALVe" }
list.Set( "SpawnableEntities", classOverride or class, table.Merge( base, extras or {} ) )
duplicator.RegisterEntityClass( class, ADD_ITEM_DUPEFUNC, "Data" )
end
local function ADD_WEAPON( class )
list.Set( "Weapon", class, { ClassName = class, PrintName = "#" .. ( class ), Category = Category, Author = "VALVe", Spawnable = true } )
duplicator.RegisterEntityClass( class, ADD_WEAPON_DUPEFUNC, "Data" )
end
local function ADD_NPC_WEAPON( class )
list.Add( "NPCUsableWeapons", { class = class, title = "#" .. class, category = Category } )
end
Category = "Half-Life 2"
-- Ammo
ADD_ITEM( "item_ammo_ar2", -8 )
ADD_ITEM( "item_ammo_ar2_large", -8 )
ADD_ITEM( "item_ammo_pistol", -4 )
ADD_ITEM( "item_ammo_pistol_large", -4 )
ADD_ITEM( "item_ammo_357", -4 )
ADD_ITEM( "item_ammo_357_large", -4 )
ADD_ITEM( "item_ammo_smg1", -2 )
ADD_ITEM( "item_ammo_smg1_large", -2 )
ADD_ITEM( "item_ammo_smg1_grenade", -10 )
ADD_ITEM( "item_ammo_crossbow", -10 )
ADD_ITEM( "item_box_buckshot", -10 )
ADD_ITEM( "item_ammo_ar2_altfire", -2 )
ADD_ITEM( "item_rpg_round", -10 )
-- Dynamic materials; gives player what he needs most (health, shotgun ammo, suit energy, etc)
-- ADD_ITEM( "item_dynamic_resupply" )
-- Items
ADD_ITEM( "item_battery", -4 )
ADD_ITEM( "item_healthkit", -8 )
ADD_ITEM( "item_healthvial", -4 )
ADD_ITEM( "item_suitcharger" )
ADD_ITEM( "item_healthcharger" )
ADD_ITEM( "item_suit", 0 )
ADD_ITEM( "prop_thumper" )
ADD_ITEM( "combine_mine", -8 )
ADD_ITEM( "combine_mine", -8, { KeyValues = { Modification = 1 } }, "combine_mine_resistance" )
ADD_ITEM( "npc_grenade_frag", -8 )
ADD_ITEM( "grenade_helicopter", 4 )
ADD_ITEM( "weapon_striderbuster" )
-- Weapons
ADD_WEAPON( "weapon_physcannon" )
ADD_WEAPON( "weapon_stunstick" )
ADD_WEAPON( "weapon_frag" )
ADD_WEAPON( "weapon_crossbow" )
ADD_WEAPON( "weapon_bugbait" )
ADD_WEAPON( "weapon_rpg" )
ADD_WEAPON( "weapon_crowbar" )
ADD_WEAPON( "weapon_shotgun" )
ADD_WEAPON( "weapon_pistol" )
ADD_WEAPON( "weapon_slam" )
ADD_WEAPON( "weapon_smg1" )
ADD_WEAPON( "weapon_ar2" )
ADD_WEAPON( "weapon_357" )
--ADD_WEAPON( "weapon_alyxgun" )
--ADD_WEAPON( "weapon_annabelle" )
-- NPC Weapons
ADD_NPC_WEAPON( "weapon_pistol" )
ADD_NPC_WEAPON( "weapon_357" )
ADD_NPC_WEAPON( "weapon_smg1" )
ADD_NPC_WEAPON( "weapon_shotgun" )
ADD_NPC_WEAPON( "weapon_ar2" )
ADD_NPC_WEAPON( "weapon_rpg" )
ADD_NPC_WEAPON( "weapon_alyxgun" )
ADD_NPC_WEAPON( "weapon_annabelle" )
ADD_NPC_WEAPON( "weapon_crossbow" )
ADD_NPC_WEAPON( "weapon_stunstick" )
ADD_NPC_WEAPON( "weapon_crowbar" )
if ( IsMounted( "hl1" ) or IsMounted( "hl1mp" ) ) then
Category = "Half-Life: Source"
ADD_WEAPON( "weapon_snark" )
ADD_WEAPON( "weapon_handgrenade" )
ADD_WEAPON( "weapon_mp5_hl1" )
ADD_WEAPON( "weapon_hornetgun" )
ADD_WEAPON( "weapon_satchel" )
ADD_WEAPON( "weapon_tripmine" )
ADD_WEAPON( "weapon_crossbow_hl1" )
ADD_WEAPON( "weapon_357_hl1" )
ADD_WEAPON( "weapon_rpg_hl1" )
ADD_WEAPON( "weapon_shotgun_hl1" )
ADD_WEAPON( "weapon_glock_hl1" )
ADD_WEAPON( "weapon_gauss" )
ADD_WEAPON( "weapon_egon" )
ADD_WEAPON( "weapon_crowbar_hl1" )
ADD_ITEM( "ammo_crossbow", 0 )
ADD_ITEM( "ammo_gaussclip", 0 )
ADD_ITEM( "ammo_glockclip", 0 )
ADD_ITEM( "ammo_mp5clip", 0 )
ADD_ITEM( "ammo_9mmbox", 0, { Information = "Gives ammo for the MP5 and Glock." } )
ADD_ITEM( "ammo_mp5grenades", 0 )
ADD_ITEM( "ammo_357", 0 )
ADD_ITEM( "ammo_rpgclip", 0 )
ADD_ITEM( "ammo_buckshot", 0 )
-- Can't be physgunned
--ADD_ITEM( "xen_plantlight", -16 )
ADD_NPC_WEAPON( "weapon_357_hl1" )
ADD_NPC_WEAPON( "weapon_mp5_hl1" )
ADD_NPC_WEAPON( "weapon_glock_hl1" )
ADD_NPC_WEAPON( "weapon_shotgun_hl1" )
end
if ( IsMounted( "portal" ) ) then
Category = "Portal"
ADD_ITEM( "prop_glados_core", 32, { KeyValues = { CoreType = 0, DelayBetweenLines = 0.4 }, PrintName = "#prop_glados_core_curiosity" } )
ADD_ITEM( "prop_glados_core", 32, { KeyValues = { CoreType = 1, DelayBetweenLines = 0.1 } }, "prop_glados_core_anger" )
ADD_ITEM( "prop_glados_core", 32, { KeyValues = { CoreType = 2, DelayBetweenLines = 0.1 } }, "prop_glados_core_crazy" )
ADD_ITEM( "prop_glados_core", 32, { KeyValues = { CoreType = 3 } }, "prop_glados_core_morality" )
end
Category = "#spawnmenu.category.other"
ADD_WEAPON( "weapon_physgun" )

127
lua/autorun/menubar.lua Normal file
View File

@@ -0,0 +1,127 @@
AddCSLuaFile()
if ( SERVER ) then return end
local checkList = {}
checkList[ "cheat" ] = { tooltip = "#menubar.cheatstip", func = function() return GetConVarNumber( "sv_cheats" ) != 0 end }
checkList[ "cheatSP" ] = { tooltip = "#menubar.cheatstip", func = function() return GetConVarNumber( "sv_cheats" ) != 0 or game.SinglePlayer() end }
checkList[ "host" ] = { tooltip = "#menubar.host_only", func = function() return IsValid( LocalPlayer() ) and LocalPlayer():IsListenServerHost() end }
local function AddCVar( s, checkStr, ... )
local cvar = s:AddCVar( ... )
cvar.OldThink = cvar.Think
cvar.Think = function( se )
se:OldThink()
local checks = string.Split( checkStr, " " )
for k, v in ipairs( checks ) do
if ( checkList[ v ] and !checkList[ v ].func() ) then
se:SetEnabled( false )
se:SetTooltip( checkList[ v ].tooltip )
return
end
end
se:SetEnabled( true )
se:SetTooltip()
end
end
local function AddHostCVar( s, ... ) AddCVar( s, "host", ... ) end
local function AddCheatCVar( s, ... ) AddCVar( s, "cheat", ... ) end
local function AddCheatOrSPCVar( s, ... ) AddCVar( s, "cheatSP host", ... ) end
-- Display options
hook.Add( "PopulateMenuBar", "DisplayOptions_MenuBar", function( menubar )
local m = menubar:AddOrGetMenu( "#menubar.drawing" )
m:AddCVar( "#menubar.drawing.physgun_beam", "physgun_drawbeams", "1", "0" )
m:AddCVar( "#menubar.drawing.physgun_halo", "physgun_halo", "1", "0" )
m:AddCVar( "#menubar.drawing.freeze", "effects_freeze", "1", "0" )
m:AddCVar( "#menubar.drawing.unfreeze", "effects_unfreeze", "1", "0" )
m:AddSpacer()
m:AddCVar( "#menubar.drawing.hud", "cl_drawhud", "1", "0" )
m:AddCVar( "#menubar.drawing.toolhelp", "gmod_drawhelp", "1", "0" )
m:AddCVar( "#menubar.drawing.toolui", "gmod_drawtooleffects", "1", "0" )
m:AddCVar( "#menubar.drawing.world_tooltips", "cl_drawworldtooltips", "1", "0" )
m:AddCVar( "#menubar.drawing.spawn_effect", "cl_drawspawneffect", "1", "0" )
m:AddCVar( "#menubar.drawing.effect_rings", "cl_draweffectrings", "1", "0" )
m:AddCVar( "#menubar.drawing.cameras", "cl_drawcameras", "1", "0" )
m:AddCVar( "#menubar.drawing.thrusters", "cl_drawthrusterseffects", "1", "0" )
m:AddSpacer()
m:AddCVar( "#menubar.drawing.shadows", "r_shadows", "1", "0" )
m:AddCVar( "#menubar.drawing.detailprops", "r_drawdetailprops", "1", "0" )
m:AddSpacer()
m:AddCVar( "#menubar.drawing.showfps", "cl_showfps", "1", "0" )
AddCheatOrSPCVar( m, "#menubar.drawing.minecraftify", "mat_showlowresimage", "1", "0", function() timer.Simple( 0.1, function() RunConsoleCommand( "mat_reloadallmaterials" ) end ) end )
AddCheatCVar( m, "#menubar.drawing.wireframe", "mat_wireframe", "1", "0" )
m:AddSpacer()
m:AddCVar( "#menubar.drawing.hints", "cl_showhints", "1", "0" )
end )
-- AI Options
hook.Add( "PopulateMenuBar", "NPCOptions_MenuBar", function( menubar )
local m = menubar:AddOrGetMenu( "#menubar.npcs" )
AddHostCVar( m, "#menubar.npcs.disableai", "ai_disabled", "1", "0" )
AddHostCVar( m, "#menubar.npcs.ignoreplayers", "ai_ignoreplayers", "1", "0" )
AddHostCVar( m, "#menubar.npcs.keepcorpses", "ai_serverragdolls", "1", "0" )
AddHostCVar( m, "#menubar.npcs.autoplayersquad", "npc_citizen_auto_player_squad", "1", "0" )
local wpns = m:AddSubMenu( "#menubar.npcs.weapon" )
wpns:SetDeleteSelf( false )
wpns:AddCVar( "#menubar.npcs.defaultweapon", "gmod_npcweapon", "" )
wpns:AddCVar( "#menubar.npcs.noweapon", "gmod_npcweapon", "none" )
wpns:AddSpacer()
local groupedWeps = {}
for _, v in pairs( list.Get( "NPCUsableWeapons" ) ) do
local cat = ( v.category or "" ):lower()
groupedWeps[ cat ] = groupedWeps[ cat ] or {}
groupedWeps[ cat ][ v.class ] = language.GetPhrase( v.title )
end
for group, items in SortedPairs( groupedWeps ) do
wpns:AddSpacer()
for class, title in SortedPairsByValue( items ) do
wpns:AddCVar( title, "gmod_npcweapon", class )
end
end
end )
-- Server options
hook.Add( "PopulateMenuBar", "MenuBar_ServerOptions", function( menubar )
local m = menubar:AddOrGetMenu( "#menubar.server" )
AddHostCVar( m, "#utilities.allowcslua", "sv_allowcslua", "1", "0" )
AddHostCVar( m, "#utilities.falldamage", "mp_falldamage", "1", "0" )
AddHostCVar( m, "#utilities.gmod_suit", "gmod_suit", "1", "0" )
AddCheatOrSPCVar( m, "#physcannon_mega_enabled", "physcannon_mega_enabled", "1", "0" )
m:AddSpacer()
AddHostCVar( m, "#enable_weapons", "sbox_weapons", "1", "0" )
AddHostCVar( m, "#allow_god_mode", "sbox_godmode", "1", "0" )
m:AddSpacer()
AddHostCVar( m, "#players_damage_players", "sbox_playershurtplayers", "1", "0" )
AddHostCVar( m, "#allow_noclip", "sbox_noclip", "1", "0" )
AddHostCVar( m, "#bone_manipulate_npcs", "sbox_bonemanip_npc", "1", "0" )
AddHostCVar( m, "#bone_manipulate_players", "sbox_bonemanip_player", "1", "0" )
AddHostCVar( m, "#bone_manipulate_others", "sbox_bonemanip_misc", "1", "0" )
end )

View File

@@ -0,0 +1,16 @@
include( "properties/bone_manipulate.lua" )
include( "properties/remove.lua" )
include( "properties/statue.lua" )
include( "properties/keep_upright.lua" )
include( "properties/persist.lua" )
include( "properties/drive.lua" )
include( "properties/ignite.lua" )
include( "properties/collisions.lua" )
include( "properties/gravity.lua" )
include( "properties/npc_scale.lua" )
include( "properties/editentity.lua" )
include( "properties/kinect_controller.lua" )
include( "properties/bodygroups.lua" )
include( "properties/skin.lua" )

View File

@@ -0,0 +1,128 @@
AddCSLuaFile()
properties.Add( "bodygroups", {
MenuLabel = "#bodygroups",
Order = 600,
MenuIcon = "icon16/link_edit.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "bodygroups", ent ) ) then return false end
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to use and modify its bodygroups instead
--
-- Get a list of bodygroups
--
local options = ent:GetBodyGroups()
if ( !options ) then return false end
--
-- If a bodygroup has more than one state - then we can configure it
--
for k, v in pairs( options ) do
if ( v.num > 1 ) then return true end
end
return false
end,
MenuOpen = function( self, option, ent, tr )
local target = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
--
-- Get a list of bodygroups
--
local options = target:GetBodyGroups()
--
-- Add a submenu to our automatically created menu option
--
local submenu = option:AddSubMenu()
--
-- For each body group - add a menu or checkbox
--
for k, v in pairs( options ) do
if ( v.num <= 1 ) then continue end
--
-- If there's only 2 options, add it as a checkbox instead of a submenu
--
if ( v.num == 2 ) then
local current = target:GetBodygroup( v.id )
local opposite = 1
if ( current == opposite ) then opposite = 0 end
local opt = submenu:AddOption( string.NiceName( v.name ) )
opt:SetChecked( current == 1 )
opt:SetIsCheckable( true )
opt.OnChecked = function( s, checked ) self:SetBodyGroup( ent, v.id, checked and 1 or 0 ) end
--
-- More than 2 options we add our own submenu
--
else
local groups = submenu:AddSubMenu( string.NiceName( v.name ) )
for i = 1, v.num do
local modelname = "Model #" .. i
if ( v.submodels and v.submodels[ i - 1 ] != "" ) then modelname = v.submodels[ i - 1 ] end
modelname = string.Trim( modelname, "." )
modelname = string.Trim( modelname, "/" )
modelname = string.Trim( modelname, "\\" )
modelname = string.StripExtension( modelname )
modelname = string.GetFileFromFilename( modelname )
local opt = groups:AddOption( string.NiceName( modelname ) )
opt:SetRadio( true )
opt:SetChecked( target:GetBodygroup( v.id ) == i - 1 )
opt:SetIsCheckable( true )
opt.OnChecked = function( s, checked ) if ( checked ) then self:SetBodyGroup( ent, v.id, i - 1 ) end end
end
end
end
end,
Action = function( self, ent )
-- Nothing - we use SetBodyGroup below
end,
SetBodyGroup = function( self, ent, body, id )
self:MsgStart()
net.WriteEntity( ent )
net.WriteUInt( body, 8 )
net.WriteUInt( id, 8 )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
local body = net.ReadUInt( 8 )
local id = net.ReadUInt( 8 )
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
ent:SetBodygroup( body, id )
end
} )

View File

@@ -0,0 +1,226 @@
AddCSLuaFile()
properties.Add( "bone_manipulate", {
MenuLabel = "#edit_bones",
Order = 500,
MenuIcon = "icon16/vector.png",
Filter = function( self, ent, ply )
if ( !gamemode.Call( "CanProperty", ply, "bonemanipulate", ent ) ) then return false end
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to use and modify its bones instead
local bonecount = ent:GetBoneCount()
if ( bonecount <= 1 ) then return false end
return ents.FindByClassAndParent( "widget_bones", ent ) == nil
end,
Action = function( self, ent )
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent.widget = ents.Create( "widget_bones" )
ent.widget:Setup( ent )
ent.widget:Spawn()
ent.widget.LastBonePress = 0
ent.widget.BonePressCount = 0
-- What happens when we click on a bone?
ent.widget.OnBoneClick = function( w, boneid, pl )
-- If we have an old axis, remove it
if ( IsValid( w.axis ) ) then w.axis:Remove() end
-- We clicked on the same bone
if ( w.LastBonePress == boneid ) then
w.BonePressCount = w.BonePressCount + 1
if ( w.BonePressCount >= 3 ) then w.BonePressCount = 0 end
-- We clicked on a new bone!
else
w.BonePressCount = 0
w.LastBonePress = boneid
end
local EntityCycle = { "widget_bonemanip_move", "widget_bonemanip_rotate", "widget_bonemanip_scale" }
w.axis = ents.Create( EntityCycle[ w.BonePressCount + 1 ] )
w.axis:Setup( ent, boneid, w.BonePressCount == 1 )
w.axis:Spawn()
w.axis:SetPriority( 0.5 )
w:DeleteOnRemove( w.axis )
end
end
} )
properties.Add( "bone_manipulate_end", {
MenuLabel = "#stop_editing_bones",
Order = 500,
MenuIcon = "icon16/vector_delete.png",
Filter = function( self, ent )
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to use and modify its bones instead
return ents.FindByClassAndParent( "widget_bones", ent ) != nil
end,
Action = function( self, ent )
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !IsValid( ent.widget ) ) then return end
ent.widget:Remove()
end
} )
local widget_bonemanip_move = {
Base = "widget_axis",
OnArrowDragged = function( self, num, dist, pl, mv )
-- Prediction doesn't work properly yet.. because of the confusion with the bone moving, and the parenting, Agh.
if ( CLIENT ) then return end
local ent = self:GetParent()
if ( !IsValid( ent ) ) then return end
local bone = self:GetParentAttachment()
if ( bone <= 0 ) then return end
local v = Vector( 0, 0, 0 )
if ( num == 1 ) then v.x = dist end
if ( num == 2 ) then v.y = dist end
if ( num == 3 ) then v.z = dist end
ent:ManipulateBonePosition( bone, ent:GetManipulateBonePosition( bone ) + v )
end,
--
-- Although we use the position from our bone, we want to use the angles from the
-- parent bone - because that's the direction our bone goes
--
CalcAbsolutePosition = function( self, v, a )
local ent = self:GetParent()
if ( !IsValid( ent ) ) then return end
local bone = ent:GetBoneParent( self:GetParentAttachment() )
if ( bone <= 0 ) then return end
local _, ang = ent:GetBonePosition( bone )
local pos, _ = ent:GetBonePosition( self:GetParentAttachment() )
return pos, ang
end
}
scripted_ents.Register( widget_bonemanip_move, "widget_bonemanip_move" )
local widget_bonemanip_rotate = {
Base = "widget_axis",
OnArrowDragged = function( self, num, dist, pl, mv )
-- Prediction doesn't work properly yet.. because of the confusion with the bone moving, and the parenting, Agh.
if ( CLIENT ) then return end
local ent = self:GetParent()
if ( !IsValid( ent ) ) then return end
local bone = self:GetParentAttachment()
if ( bone <= 0 ) then return end
local v = Angle( 0, 0, 0 )
if ( num == 2 ) then v.x = dist end
if ( num == 3 ) then v.y = dist end
if ( num == 1 ) then v.z = dist end
ent:ManipulateBoneAngles( bone, ent:GetManipulateBoneAngles( bone ) + v )
end
}
scripted_ents.Register( widget_bonemanip_rotate, "widget_bonemanip_rotate" )
local widget_bonemanip_scale = {
Base = "widget_axis",
IsScaleArrow = true,
OnArrowDragged = function( self, num, dist, pl, mv )
-- Prediction doesn't work properly yet.. because of the confusion with the bone moving, and the parenting, Agh.
if ( CLIENT ) then return end
local ent = self:GetParent()
if ( !IsValid( ent ) ) then return end
local bone = self:GetParentAttachment()
if ( bone <= 0 ) then return end
local v = Vector( 0, 0, 0 )
if ( num == 1 ) then v.x = dist end
if ( num == 2 ) then v.y = dist end
if ( num == 3 ) then v.z = dist end
ent:ManipulateBoneScale( bone, ent:GetManipulateBoneScale( bone ) + v * 0.1 )
ent:ManipulateBoneScale( ent:GetBoneParent( bone ), ent:GetManipulateBoneScale( ent:GetBoneParent( bone ) ) + v )
end,
--
-- Although we use the position from our bone, we want to use the angles from the
-- parent bone - because that's the direction our bone goes
--
CalcAbsolutePosition = function( self, v, a )
local ent = self:GetParent()
if ( !IsValid( ent ) ) then return end
local bone = self:GetParentAttachment()
if ( bone <= 0 ) then return end
local pbone = ent:GetBoneParent( bone )
if ( pbone <= 0 ) then return end
local pos, ang = ent:GetBonePosition( bone )
local pos2, _ = ent:GetBonePosition( pbone )
return pos + ( pos2 - pos ) * 0.5, ang
end
}
scripted_ents.Register( widget_bonemanip_scale, "widget_bonemanip_scale" )

View File

@@ -0,0 +1,73 @@
AddCSLuaFile()
properties.Add( "collision_off", {
MenuLabel = "#collision_off",
Order = 1500,
MenuIcon = "icon16/collision_off.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "collision", ent ) ) then return false end
if ( ent:GetCollisionGroup() == COLLISION_GROUP_WORLD ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent:SetCollisionGroup( COLLISION_GROUP_WORLD )
end
} )
properties.Add( "collision_on", {
MenuLabel = "#collision_on",
Order = 1500,
MenuIcon = "icon16/collision_on.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "collision", ent ) ) then return false end
return ent:GetCollisionGroup() == COLLISION_GROUP_WORLD
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent:SetCollisionGroup( COLLISION_GROUP_NONE )
end
} )

View File

@@ -0,0 +1,52 @@
AddCSLuaFile()
properties.Add( "drive", {
MenuLabel = "#drive",
Order = 1100,
MenuIcon = "icon16/joystick.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) || !IsValid( ply ) ) then return false end
if ( ent:IsPlayer() || IsValid( ply:GetVehicle() ) ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "drive", ent ) ) then return false end
if ( !gamemode.Call( "CanDrive", ply, ent ) ) then return false end
-- We cannot drive these, maybe this should have a custom GetEntityDriveMode?
if ( ent:GetClass() == "prop_vehicle_jeep" || ent:GetClass() == "prop_vehicle_jeep_old" ) then return false end
-- Make sure nobody else is driving this or we can get into really invalid states
for id, pl in player.Iterator() do
if ( pl:GetDrivingEntity() == ent ) then return false end
end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
local drivemode = "drive_sandbox"
if ( ent.GetEntityDriveMode ) then
drivemode = ent:GetEntityDriveMode( ply )
end
drive.PlayerStartDriving( ply, ent, drivemode )
end
} )

View File

@@ -0,0 +1,48 @@
AddCSLuaFile()
properties.Add( "editentity", {
MenuLabel = "#entedit",
Order = 90001,
PrependSpacer = true,
MenuIcon = "icon16/pencil.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( !ent.Editable ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "editentity", ent ) ) then return false end
return true
end,
Action = function( self, ent )
local printName = ent.PrintName
if ( !isstring( printName ) ) then
printName = ent:GetClass()
end
printName = language.GetPhrase( printName )
printName = string.format( "%s [%d]", printName, ent:EntIndex() )
local window = g_ContextMenu:Add( "DFrame" )
window:SetSize( 320, 400 )
window:SetTitle( printName )
window:Center()
window:SetSizable( true )
local control = window:Add( "DEntityProperties" )
control:SetEntity( ent )
control:Dock( FILL )
control.OnEntityLost = function()
window:Remove()
end
end
} )

View File

@@ -0,0 +1,82 @@
AddCSLuaFile()
-- The following is for the server's eyes only
local GravityDuplicator
if ( SERVER ) then
function GravityDuplicator( ply, ent, data )
if ( !data || !data.enabled ) then
duplicator.ClearEntityModifier( ent, "gravity_property" )
return
end
-- Simply restore the value whenever we are duplicated
-- We don't need to reapply EnableGravity because duplicator already does it for us
ent:SetNWBool( "gravity_disabled", data.enabled )
duplicator.StoreEntityModifier( ent, "gravity_property", data )
end
duplicator.RegisterEntityModifier( "gravity_property", GravityDuplicator )
end
properties.Add( "gravity", {
MenuLabel = "#gravity",
Type = "toggle",
Order = 1001,
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "gravity", ent ) ) then return false end
if ( ent:GetClass() == "prop_physics" ) then return true end
if ( ent:GetClass() == "prop_ragdoll" ) then return true end
return false
end,
Checked = function( self, ent, ply )
return ent:GetNWBool( "gravity_disabled" ) == false
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
local bones = ent:GetPhysicsObjectCount()
local b = ent:GetNWBool( "gravity_disabled" )
for i = 0, bones - 1 do
local phys = ent:GetPhysicsObjectNum( i )
if ( IsValid( phys ) ) then
phys:EnableGravity( b )
phys:Wake()
end
end
ent:SetNWBool( "gravity_disabled", b == false )
GravityDuplicator( ply, ent, { enabled = ent:GetNWBool( "gravity_disabled" ) } )
end
} )

View File

@@ -0,0 +1,88 @@
AddCSLuaFile()
local function CanEntityBeSetOnFire( ent )
local class = ent:GetClass()
-- func_pushable, func_breakable & func_physbox cannot be ignited
if ( class == "item_item_crate" ) then return true end
if ( class == "simple_physics_prop" ) then return true end
if ( class:match( "prop_physics*" ) ) then return true end
if ( class:match( "prop_ragdoll*" ) ) then return true end
if ( ent:IsNPC() ) then return true end
return false
end
properties.Add( "ignite", {
MenuLabel = "#ignite",
Order = 999,
MenuIcon = "icon16/fire.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
if ( !CanEntityBeSetOnFire( ent ) ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "ignite", ent ) ) then return false end
return !ent:IsOnFire()
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent:Ignite( 360 )
end
} )
properties.Add( "extinguish", {
MenuLabel = "#extinguish",
Order = 999,
MenuIcon = "icon16/water.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "extinguish", ent ) ) then return false end
return ent:IsOnFire()
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent:Extinguish()
end
} )

View File

@@ -0,0 +1,97 @@
AddCSLuaFile()
properties.Add( "keepupright", {
MenuLabel = "#keepupright",
Order = 900,
MenuIcon = "icon16/arrow_up.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:GetClass() != "prop_physics" ) then return false end
if ( ent:GetNWBool( "IsUpright" ) ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "keepupright", ent ) ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !IsValid( ply ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( ent:GetClass() != "prop_physics" ) then return end
if ( ent:GetNWBool( "IsUpright" ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
local Phys = ent:GetPhysicsObjectNum( 0 )
if ( !IsValid( Phys ) ) then return end
local constraint = constraint.Keepupright( ent, Phys:GetAngles(), 0, 999999 )
-- I feel like this is not stable enough
-- This cannot be implemented without a custom constraint.Keepupright function or modification for proper duplicator support.
--print( constraint:GetSaveTable().m_worldGoalAxis )
--constraint:SetSaveValue( "m_localTestAxis", constraint:GetSaveTable().m_worldGoalAxis ) --ent:GetAngles():Up() )
--constraint:SetSaveValue( "m_worldGoalAxis", Vector( 0, 0, 1 ) )
--constraint:SetSaveValue( "m_bDampAllRotation", true )
if ( constraint ) then
ply:AddCleanup( "constraints", constraint )
ent:SetNWBool( "IsUpright", true )
end
end
} )
properties.Add( "keepupright_stop", {
MenuLabel = "#keepupright_stop",
Order = 900,
MenuIcon = "icon16/arrow_rotate_clockwise.png",
Filter = function( self, ent )
if ( !IsValid( ent ) ) then return false end
if ( ent:GetClass() != "prop_physics" ) then return false end
if ( !ent:GetNWBool( "IsUpright" ) ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !IsValid( ply ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( ent:GetClass() != "prop_physics" ) then return end
if ( !ent:GetNWBool( "IsUpright" ) ) then return end
constraint.RemoveConstraints( ent, "Keepupright" )
ent:SetNWBool( "IsUpright", false )
end
} )

View File

@@ -0,0 +1,81 @@
AddCSLuaFile()
if ( SERVER ) then
CreateConVar( "sensor_debugragdoll", "0", FCVAR_NOTIFY )
CreateConVar( "sensor_stretchragdoll", "0", FCVAR_NOTIFY )
end
local playerTimeouts = {}
properties.Add( "motioncontrol_ragdoll", {
MenuLabel = "#control_with_motion_sensor",
Order = 2500,
MenuIcon = "icon16/controller.png",
Filter = function( self, ent, ply )
if ( CLIENT && !motionsensor ) then return false end
if ( CLIENT && !motionsensor.IsAvailable() ) then return false end
if ( !ent:IsRagdoll() ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "motioncontrol_ragdoll", ent ) ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
--
-- Start up the kinect controller. This will freeze the game for a second.
--
if ( !motionsensor.IsActive() ) then
motionsensor.Start()
end
end,
Receive = function( self, length, player )
local ent = net.ReadEntity()
if ( !self:Filter( ent, player ) ) then return end
-- Do not spam please!
local timeout = playerTimeouts[ player ]
if ( timeout && timeout.time > CurTime() ) then
if ( !timeout.sentMessage ) then
ServerLog( "Player " .. tostring( player ) .. " tried to use 'motioncontrol_ragdoll' property too rapidly!\n" )
player:PrintMessage( HUD_PRINTTALK, "Please wait at least 0.2 seconds before trying to control another ragdoll." )
timeout.sentMessage = true
end
return
end
-- Only 1 controller per ragdoll please!
if ( IsValid( ent.MotionSensorController ) ) then
ent.MotionSensorController:Remove()
end
local ragdoll_motion = ents.Create( "ragdoll_motion" )
ragdoll_motion:SetPos( player:EyePos() + player:EyeAngles():Forward() * 10 )
ragdoll_motion:SetAngles( Angle( 0, player:EyeAngles().yaw, 0 ) )
ragdoll_motion:SetRagdoll( ent )
ragdoll_motion:SetController( player )
ragdoll_motion:Spawn()
undo.Create( "ragdoll_motion" )
undo.AddEntity( ragdoll_motion )
undo.SetPlayer( player )
undo.Finish()
playerTimeouts[ player ] = { time = CurTime() + 0.2, sentMessage = false }
end
} )

View File

@@ -0,0 +1,72 @@
AddCSLuaFile()
properties.Add( "npc_bigger", {
MenuLabel = "#biggify",
Order = 1799,
MenuIcon = "icon16/magnifier_zoom_in.png",
Filter = function( self, ent, ply )
if ( !gamemode.Call( "CanProperty", ply, "npc_bigger", ent ) ) then return false end
if ( !IsValid( ent ) ) then return false end
if ( !ent:IsNPC() ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent:SetModelScale( ent:GetModelScale() * 1.25, 1 )
end
} )
properties.Add( "npc_smaller", {
MenuLabel = "#smallify",
Order = 1800,
MenuIcon = "icon16/magifier_zoom_out.png",
Filter = function( self, ent, ply )
if ( !gamemode.Call( "CanProperty", ply, "npc_smaller", ent ) ) then return false end
if ( !IsValid( ent ) ) then return false end
if ( !ent:IsNPC() ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent:SetModelScale( ent:GetModelScale() * 0.8, 1 )
end
} )

View File

@@ -0,0 +1,79 @@
AddCSLuaFile()
properties.Add( "persist", {
MenuLabel = "#makepersistent",
Order = 400,
MenuIcon = "icon16/link.png",
Filter = function( self, ent, ply )
if ( ent:IsPlayer() ) then return false end
if ( GetConVarString( "sbox_persist" ):Trim() == "" ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "persist", ent ) ) then return false end
return !ent:GetPersistent()
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
-- TODO: Start some kind of animation, take 5 seconds to make something persistent
ent:SetPersistent( true )
--ent:EnableMotion( false )
end
} )
properties.Add( "persist_end", {
MenuLabel = "#stoppersisting",
Order = 400,
MenuIcon = "icon16/link_break.png",
Filter = function( self, ent, ply )
if ( ent:IsPlayer() ) then return false end
if ( GetConVarString( "sbox_persist" ):Trim() == "" ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "persist", ent ) ) then return false end
return ent:GetPersistent()
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
-- TODO: Start some kind of animation, take 5 seconds to make something persistent
ent:SetPersistent( false )
end
} )

View File

@@ -0,0 +1,57 @@
AddCSLuaFile()
properties.Add( "remove", {
MenuLabel = "#remove",
Order = 1000,
MenuIcon = "icon16/delete.png",
Filter = function( self, ent, ply )
if ( !gamemode.Call( "CanProperty", ply, "remover", ent ) ) then return false end
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
if ( !IsValid( ply ) ) then return end
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
-- Don't allow removal of players or objects that cannot be physically targeted by properties
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
-- Remove all constraints (this stops ropes from hanging around)
constraint.RemoveAll( ent )
-- Remove it properly in 1 second
timer.Simple( 1, function() if ( IsValid( ent ) ) then ent:Remove() end end )
-- Make it non solid
ent:SetNotSolid( true )
ent:SetMoveType( MOVETYPE_NONE )
ent:SetNoDraw( true )
-- Send Effect
local ed = EffectData()
ed:SetEntity( ent )
util.Effect( "entity_remove", ed, true, true )
ply:SendLua( "achievements.Remover()" )
end
} )

View File

@@ -0,0 +1,75 @@
AddCSLuaFile()
properties.Add( "skin", {
MenuLabel = "#skin",
Order = 601,
MenuIcon = "icon16/picture_edit.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:IsPlayer() ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "skin", ent ) ) then return false end
if ( IsValid( ent.AttachedEntity ) ) then ent = ent.AttachedEntity end -- If our ent has an attached entity, we want to modify its skin instead
if ( !ent:SkinCount() ) then return false end
return ent:SkinCount() > 1
end,
MenuOpen = function( self, option, ent, tr )
--
-- Add a submenu to our automatically created menu option
--
local submenu = option:AddSubMenu()
--
-- Create a check item for each skin
--
local target = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
local num = target:SkinCount()
for i = 0, num - 1 do
local opt = submenu:AddOption( "Skin " .. i )
opt:SetRadio( true )
opt:SetChecked( target:GetSkin() == i )
opt:SetIsCheckable( true )
opt.OnChecked = function( s, checked ) if ( checked ) then self:SetSkin( ent, i ) end end
end
end,
Action = function( self, ent )
-- Nothing - we use SetSkin below
end,
SetSkin = function( self, ent, id )
self:MsgStart()
net.WriteEntity( ent )
net.WriteUInt( id, 8 )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
local skinid = net.ReadUInt( 8 )
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( !self:Filter( ent, ply ) ) then return end
ent = IsValid( ent.AttachedEntity ) and ent.AttachedEntity or ent
ent:SetSkin( skinid )
end
} )

View File

@@ -0,0 +1,194 @@
AddCSLuaFile()
-- The following is for the server's eyes only
local StatueDuplicator
if ( SERVER ) then
function StatueDuplicator( ply, ent, data )
if ( !data ) then
duplicator.ClearEntityModifier( ent, "statue_property" )
return
end
-- We have been pasted from duplicator, restore the necessary variables for the unstatue to work
if ( ent.StatueInfo == nil ) then
-- Ew. Have to wait a frame for the constraints to get pasted
timer.Simple( 0, function()
if ( !IsValid( ent ) ) then return end
local bones = ent:GetPhysicsObjectCount()
if ( bones < 2 ) then return end
ent:SetNWBool( "IsStatue", true )
ent.StatueInfo = {}
local con = constraint.FindConstraints( ent, "Weld" )
for id, t in pairs( con ) do
if ( t.Ent1 != t.Ent2 || t.Ent1 != ent || t.Bone1 != 0 ) then continue end
ent.StatueInfo[ t.Bone2 ] = t.Constraint
end
local numC = table.Count( ent.StatueInfo )
if ( numC < 1 --[[or numC != bones - 1]] ) then duplicator.ClearEntityModifier( ent, "statue_property" ) end
end )
end
duplicator.StoreEntityModifier( ent, "statue_property", data )
end
duplicator.RegisterEntityModifier( "statue_property", StatueDuplicator )
end
local playerTimeouts = {}
properties.Add( "statue", {
MenuLabel = "#makestatue",
Order = 1501,
MenuIcon = "icon16/lock.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:GetClass() != "prop_ragdoll" ) then return false end
if ( ent:GetNWBool( "IsStatue" ) ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "statue", ent ) ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !IsValid( ply ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( ent:GetClass() != "prop_ragdoll" ) then return end
if ( !self:Filter( ent, ply ) ) then return end
-- Do not spam please!
local timeout = playerTimeouts[ ply ]
if ( timeout && timeout.time > CurTime() ) then
if ( !timeout.sentMessage ) then
ServerLog( "Player " .. tostring( ply ) .. " tried to use 'statue' property too rapidly!\n" )
ply:PrintMessage( HUD_PRINTTALK, "Please wait at least 0.2 seconds before trying to make another ragdoll a statue." )
timeout.sentMessage = true
end
return
end
local bones = ent:GetPhysicsObjectCount()
if ( bones < 2 ) then return end
if ( ent.StatueInfo ) then return end
ent.StatueInfo = {}
undo.Create( "Statue" )
for bone = 1, bones - 1 do
local constr = constraint.Weld( ent, ent, 0, bone, 0 )
if ( constr ) then
ent.StatueInfo[ bone ] = constr
ply:AddCleanup( "constraints", constr )
undo.AddEntity( constr )
end
local effectdata = EffectData()
effectdata:SetOrigin( ent:GetPhysicsObjectNum( bone ):GetPos() )
effectdata:SetScale( 1 )
effectdata:SetMagnitude( 1 )
util.Effect( "GlassImpact", effectdata, true, true )
end
ent:SetNWBool( "IsStatue", true )
undo.AddFunction( function()
if ( !IsValid( ent ) ) then return false end
ent:SetNWBool( "IsStatue", false )
ent.StatueInfo = nil
StatueDuplicator( ply, ent, nil )
end )
undo.SetPlayer( ply )
undo.SetCustomUndoText( "Undone #makestatue" )
undo.Finish( "#makestatue" )
StatueDuplicator( ply, ent, {} )
playerTimeouts[ ply ] = { time = CurTime() + 0.2, sentMessage = false }
end
} )
properties.Add( "statue_stop", {
MenuLabel = "#unstatue",
Order = 1501,
MenuIcon = "icon16/lock_open.png",
Filter = function( self, ent, ply )
if ( !IsValid( ent ) ) then return false end
if ( ent:GetClass() != "prop_ragdoll" ) then return false end
if ( !ent:GetNWBool( "IsStatue" ) ) then return false end
if ( !gamemode.Call( "CanProperty", ply, "unstatue", ent ) ) then return false end
return true
end,
Action = function( self, ent )
self:MsgStart()
net.WriteEntity( ent )
self:MsgEnd()
end,
Receive = function( self, length, ply )
local ent = net.ReadEntity()
if ( !IsValid( ent ) ) then return end
if ( !IsValid( ply ) ) then return end
if ( !properties.CanBeTargeted( ent, ply ) ) then return end
if ( ent:GetClass() != "prop_ragdoll" ) then return end
if ( !self:Filter( ent, ply ) ) then return end
local bones = ent:GetPhysicsObjectCount()
if ( bones < 2 ) then return end
if ( !ent.StatueInfo ) then return end
for k, v in pairs( ent.StatueInfo ) do
if ( IsValid( v ) ) then
v:Remove()
end
end
ent:SetNWBool( "IsStatue", false )
ent.StatueInfo = nil
StatueDuplicator( ply, ent, nil )
end
} )

View File

@@ -0,0 +1,35 @@
--[[---------------------------------------------------------
Name: KickId2
Desc: Allows admins to use the kickid2 command to kick people.
-----------------------------------------------------------]]
local function KickId( player, command, arguments )
if ( !player:IsAdmin() ) then return end
local id = arguments[1]
local reason = arguments[2] or "Kicked"
RunConsoleCommand( "kickid", id, Format( "%s (%s)", reason, player:Nick() ) )
end
concommand.Add( "kickid2", KickId, nil, "Alias of kickid, do not use.", { FCVAR_DONTRECORD } )
--[[---------------------------------------------------------
Name: BanId2
Desc: Allows admins to use the banid2 command to ban people.
-----------------------------------------------------------]]
local function BanID( player, command, arguments )
if ( !player:IsAdmin() ) then return end
local length = arguments[1]
local id = arguments[2]
RunConsoleCommand( "banid", length, id )
end
concommand.Add( "banid2", BanID, nil, "Alias of banid, do not use.", { FCVAR_DONTRECORD } )

View File

@@ -0,0 +1,119 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local SPNE = 1
local TRSO = 2
local RSLD = 3
local LSLD = 4
local LARM = 5
local LWST = 6
local LHND = 7
local RARM = 8
local RWST = 9
local RHND = 10
local RTHY = 11
local RCLF = 12
local LTHY = 13
local LCLF = 14
local HEAD = 15
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 1.0
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.5 )
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * 0.2 )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * 0.2 )
-- sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * 0.3 )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[TRSO] = SENSORBONE.SPINE,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = SENSORBONE.SPINE,
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = LTHY, to = RTHY, up = "hips_fwd" },
[SPNE] = { from_sensor = SENSORBONE.HEAD, to_sensor = SENSORBONE.SPINE, up = "chest_rgt" },
[TRSO] = { from_sensor = SENSORBONE.HEAD, to_sensor = SENSORBONE.SPINE, up = "chest_rgt" },
[HEAD] = { from_sensor = SENSORBONE.HEAD, to_sensor = SENSORBONE.SHOULDER, up = "chest_lft" },
[RSLD] = { from = RSLD, to = LSLD, up = "chest_bck" },
[LSLD] = { from = LSLD, to = RSLD, up = "chest_fwd" },
[RARM] = { from = RARM, to = RSLD, up = "chest_up" },
[LARM] = { from = LARM, to = LSLD, up = "chest_dn" },
[RWST] = { from = RHND, to = RARM, up = "chest_up" },
[LWST] = { from = LHND, to = LARM, up = "chest_dn" },
[RTHY] = { from = RCLF, to = RTHY, up_up = SPNE },
[RCLF] = { from_sensor = SENSORBONE.ANKLE_RIGHT, to_sensor = SENSORBONE.KNEE_RIGHT, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up_up = SPNE },
[LCLF] = { from_sensor = SENSORBONE.ANKLE_LEFT, to_sensor = SENSORBONE.KNEE_LEFT, up_up = LTHY },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_lft = RARM },
[LHND] = { from_sensor = SENSORBONE.HAND_LEFT, to_sensor = SENSORBONE.WRIST_LEFT, up_rgt = LARM },
[LWST] = { from = LHND, to = LARM, up = "chest_dn" },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
pos[SPNE] = LerpVector( 0.45, pos[SPNE], pos[HEAD] )
pos[RWST] = pos[RARM]
pos[LWST] = pos[LARM]
end,
-- We're used as a default - no need to return true to anything here.
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/ct_gign.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/ct_sas.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/ct_urban.mdl" ) ) then return true end
if ( mdl:EndsWith( "models//player/ct_gsg9.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/t_guerilla.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/t_leet.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/t_phoenix.mdl" ) ) then return true end
if ( mdl:EndsWith( "models//player/t_arctic.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "CounterStrikeSource", Builder )

View File

@@ -0,0 +1,104 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local LTHY = 1
local SPNE = 2
local RSLD = 3
local RARM = 4
local LSLD = 5
local LARM = 6
local LHND = 7
local HEAD = 8
local RHND = 9
local RTHY = 10
local RCLF = 11
local LCLF = 12
local RFOT = 13
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.7
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.5 )
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * 0.3 )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * 0.3 )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.HIP_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.2 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.2 )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = SENSORBONE.SPINE,
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = LTHY, to = RTHY, up = "hips_fwd" },
[SPNE] = { from = HEAD, to = SPNE, up = "chest_rgt" },
[HEAD] = { from_sensor = SENSORBONE.HEAD, to_sensor = SENSORBONE.SPINE, up = "chest_lft" },
[RSLD] = { from = RARM, to = RSLD, up = "chest_up" },
[RARM] = { from = RHND, to = RARM, up_up = RSLD },
[LSLD] = { from = LARM, to = LSLD, up = "chest_dn" },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[RTHY] = { from = RCLF, to = RTHY, up_up = SPNE },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up_up = SPNE },
[LCLF] = { from_sensor = SENSORBONE.ANKLE_LEFT, to = LCLF, up_up = LTHY },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_lft = RARM },
[LHND] = { from_sensor = SENSORBONE.HAND_LEFT, to_sensor = SENSORBONE.WRIST_LEFT, up_rgt = LARM }
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
pos[SPNE] = LerpVector( 0.4, pos[SPNE], pos[HEAD] )
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 20, 0, 0 )
end,
-- Should this entity use this builder?
IsApplicable = function( self, ent )
return ent:GetModel():EndsWith( "models/eli.mdl" )
end,
}
list.Set( "SkeletonConvertor", "Eli", Builder )

View File

@@ -0,0 +1,163 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
-- coord
local RTHY = 2
local RCLF = 3
local RFOT = 4
local LTHY = 5
local LCLF = 6
local LFOT = 7
local SPNE = 8
local RSLD = 9
local RARM = 10
local LSLD = 11
local LARM = 12
local LHND = 13
local NECK = 14
local HEAD = 15
local RHND = 16
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.6
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.9 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.06
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.0 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.0 - acrosships )
sensor[SENSORBONE.FOOT_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.2 + acrosships )
sensor[SENSORBONE.FOOT_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.2 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.2 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.2 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[NECK] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = PLVS, to = SPNE, up = "chest_bck" },
[HEAD] = { from = SPNE, to = HEAD, up = "head_back" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = SPNE },
[RARM] = { from = RHND, to = RARM, up_rgt = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_fwd = RARM },
[LSLD] = { from = LARM, to = LSLD, up_lft = SPNE },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[LHND] = { from_sensor = SENSORBONE.WRIST_LEFT, to_sensor = SENSORBONE.HAND_LEFT, up_bck = LARM },
[RTHY] = { from = RCLF, to = RTHY, up_dn = PLVS },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[RFOT] = { from = RCLF, to = RFOT, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up_dn = PLVS },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
[LFOT] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT]:RotateAroundAxis( ang[RFOT]:Up(), -90 )
ang[RFOT]:RotateAroundAxis( ang[RFOT]:Forward(), 180 )
ang[LFOT]:RotateAroundAxis( ang[LFOT]:Up(), 90 )
ang[LFOT]:RotateAroundAxis( ang[LFOT]:Forward(), -45 )
ang[RFOT]:RotateAroundAxis( ang[LFOT]:Forward(), -45 )
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
ang[NECK] = ang[HEAD]
pos[1] = pos[PLVS]
ang[1] = ang[PLVS] * -1
ang[1]:RotateAroundAxis( ang[1]:Right(), 90 )
pos[17] = pos[PLVS]
ang[17] = ang[PLVS] * -1
ang[17]:RotateAroundAxis( ang[1]:Right(), 90 )
--
-- AGH HANDS
--
ang[LHND] = ang[LARM] * 1
ang[LHND]:RotateAroundAxis( ang[LHND]:Up(), 90 )
ang[RHND] = ang[RARM] * 1
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/engineer.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/engineer.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/engineer/bot_engineer.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/demo_engineer/bot_demo_engineer.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_engineer", Builder )

View File

@@ -0,0 +1,147 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local RTHY = 1
local RCLF = 2
local LTHY = 3
local LCLF = 4
local LFOT = 5
local SPNE = 6
local SPN2 = 7
local RSLD = 8
local LSLD = 9
local LARM = 10
local LHND = 11
local RARM = 12
local RHND = 13
local HEAD = 14
local RFOT = 15
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 1.2
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.6 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.9 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.06
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.3 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.3 - acrosships )
sensor[SENSORBONE.FOOT_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.2 + acrosships )
sensor[SENSORBONE.FOOT_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.2 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.2 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.2 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE },
[SPN2] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = PLVS, to = SPNE, up = "chest_bck" },
[SPN2] = { from = PLVS, to = SPNE, up = "chest_bck" },
[HEAD] = { from = SPNE, to = HEAD, up = "head_back" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = SPNE },
[RARM] = { from = RHND, to = RARM, up_rgt = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_fwd = RARM },
[LSLD] = { from = LARM, to = LSLD, up_lft = SPNE },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[LHND] = { from_sensor = SENSORBONE.WRIST_LEFT, to_sensor = SENSORBONE.HAND_LEFT, up_bck = LARM },
[RTHY] = { from = RCLF, to = RTHY, up = "right" },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up = "forward" },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 0, 180, -40 )
ang[LFOT] = ang[LCLF]:Right():AngleEx( ang[LCLF]:Up() ) + Angle( 0, -90, 130 )
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[SPN2]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
--
-- AGH HANDS
--
ang[LHND] = ang[LARM] * 1
ang[LHND]:RotateAroundAxis( ang[LHND]:Up(), 90 )
ang[RHND] = ang[RARM] * 1
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/heavy.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/heavy.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/heavy/bot_heavy.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/heavy_boss/bot_heavy_boss.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_heavy", Builder )

View File

@@ -0,0 +1,143 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
-- Coat 1-9
local RTHY = 10
local RCLF = 11
-- Coat 12
local LTHY = 13
local LCLF = 14
local LFOT = 15
local SPNE = 16
local RSLD = 17
local RARM = 18
local LSLD = 19
local LARM = 20
local HEAD = 21
local RHND = 22
local RFOT = 23
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.6
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.6 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.9 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.06
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.1 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.1 - acrosships )
sensor[SENSORBONE.FOOT_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.0 + acrosships )
sensor[SENSORBONE.FOOT_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.0 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.0 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.0 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = PLVS, to = SPNE, up = "chest_bck" },
[HEAD] = { from = SPNE, to = HEAD, up = "head_back" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = SPNE },
[RARM] = { from = RHND, to = RARM, up_rgt = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_fwd = RARM },
[LSLD] = { from = LARM, to = LSLD, up_lft = SPNE },
[LARM] = { from_sensor = SENSORBONE.HAND_LEFT, to_sensor = SENSORBONE.ELBOW_LEFT, up_up = LSLD },
[RTHY] = { from = RCLF, to = RTHY, up = "right" },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up = "forward" },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 0, 180, -40 )
ang[LFOT] = ang[LCLF]:Right():AngleEx( ang[LCLF]:Up() ) + Angle( 0, -90, 130 )
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
--
-- AGH HANDS
--
ang[RHND] = ang[RARM] * 1
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/medic.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/medic.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/medic/bot_medic.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/medic_boss/bot_medic_boss.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_medic", Builder )

View File

@@ -0,0 +1,147 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local RTHY = 1
local RCLF = 2
local LTHY = 3
local LCLF = 4
local LFOT = 5
local SPNE = 6
local RSLD = 7
local RARM = 8
local LSLD = 9
local LARM = 10
local LHND = 11
local HEAD = 12
local RHND = 13
local RFOT = 14
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.6
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.9 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.06
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.3 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.3 - acrosships )
sensor[SENSORBONE.FOOT_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.2 + acrosships )
sensor[SENSORBONE.FOOT_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.2 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.2 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.2 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = PLVS, to = SPNE, up = "chest_bck" },
[HEAD] = { from = SPNE, to = HEAD, up = "head_back" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = SPNE },
[RARM] = { from = RHND, to = RARM, up_rgt = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_fwd = RARM },
[LSLD] = { from = LARM, to = LSLD, up_lft = SPNE },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[LHND] = { from_sensor = SENSORBONE.WRIST_LEFT, to_sensor = SENSORBONE.HAND_LEFT, up_bck = LARM },
[RTHY] = { from = RCLF, to = RTHY, up = "right" },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up = "forward" },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 0, 180, -40 )
ang[LFOT] = ang[LCLF]:Right():AngleEx( ang[LCLF]:Up() ) + Angle( 0, -90, 130 )
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
--
-- AGH HANDS
--
ang[LHND] = ang[LARM] * 1
ang[LHND]:RotateAroundAxis( ang[LHND]:Up(), 90 )
ang[RHND] = ang[RARM] * 1
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel();
if ( mdl:EndsWith( "models/player/pyro.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/pyro.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/pyro/bot_pyro.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/demo.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/demo.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/pyro/bot_demo.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/pyro_boss/bot_pyro_boss.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/demo_boss/bot_demo_boss.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_pyro", Builder )

View File

@@ -0,0 +1,150 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local RTHY = 1
local RCLF = 2
local LTHY = 3
local LCLF = 4
local LFOT = 5
local SPNE = 6
local RSLD = 7
local RARM = 8
local LSLD = 9
local LARM = 10
local LHND = 11
local NECK = 12
local HEAD = 13
local DGTG = 14
local RHND = 15
local RFOT = 16
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.5
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.9 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.06
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.3 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.3 - acrosships )
sensor[SENSORBONE.FOOT_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.2 + acrosships )
sensor[SENSORBONE.FOOT_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.2 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 1.2 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 1.2 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
--[TRSO] = { type = "lerp", value = 0.2, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE },
[NECK] = { type = "lerp", value = 0.5, from = SENSORBONE.SHOULDER, to = SENSORBONE.HEAD },
[DGTG] = { type = "lerp", value = 0.2, from = SENSORBONE.SHOULDER, to = SENSORBONE.HIP },
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = PLVS, to = SPNE, up = "chest_bck" },
[HEAD] = { from = NECK, to = HEAD, up = "head_back" },
[NECK] = { from = SPNE, to = NECK, up = "head_back" },
[DGTG] = { from = NECK, to = DGTG, up = "chest_up" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = SPNE },
[RARM] = { from = RHND, to = RARM, up_rgt = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_fwd = RARM },
[LSLD] = { from = LARM, to = LSLD, up_dn = SPNE },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[LHND] = { from_sensor = SENSORBONE.WRIST_LEFT, to_sensor = SENSORBONE.HAND_LEFT, up_bck = LARM },
[RTHY] = { from = RCLF, to = RTHY, up = "right" },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up = "forward" },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 0, 180, -40 )
ang[LFOT] = ang[LCLF]:Right():AngleEx( ang[LCLF]:Up() ) + Angle( 0, -90, 130 )
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[NECK]:RotateAroundAxis( ang[NECK]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
--
-- AGH HANDS
--
ang[LHND] = ang[LARM] * 1
ang[LHND]:RotateAroundAxis( ang[LHND]:Up(), 90 )
ang[RHND] = ang[RARM] * 1
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/scout.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/scout.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/scout/bot_scout.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_scout", Builder )

View File

@@ -0,0 +1,159 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local RTHY = 1
local RCLF = 2
local RFOT = 3
local LTHY = 4
local LCLF = 5
local LFOT = 6
local SPNE = 7
local RSLD = 8
local RARM = 9
local LSLD = 10
local LARM = 11
local LHND = 12
local NECK = 13
local HEAD = 14
local RHND = 15
-- pouch
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.8
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.9 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.06
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.3 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.3 - acrosships )
sensor[SENSORBONE.FOOT_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.6 + acrosships )
sensor[SENSORBONE.FOOT_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.6 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.6 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.6 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[NECK] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = PLVS, to = SPNE, up = "chest_bck" },
[HEAD] = { from = SPNE, to = HEAD, up = "head_back" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = SPNE },
[RARM] = { from = RHND, to = RARM, up_rgt = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_fwd = RARM },
[LSLD] = { from = LARM, to = LSLD, up_lft = SPNE },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[LHND] = { from_sensor = SENSORBONE.WRIST_LEFT, to_sensor = SENSORBONE.HAND_LEFT, up_bck = LARM },
[RTHY] = { from = RCLF, to = RTHY, up_dn = PLVS },
[RCLF] = { from = RFOT, to = RCLF, up_lft = RTHY },
[RFOT] = { from = RCLF, to = RFOT, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up_dn = PLVS },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
[LFOT] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT]:RotateAroundAxis( ang[RFOT]:Up(), -90 )
ang[RFOT]:RotateAroundAxis( ang[RFOT]:Forward(), 180 )
ang[LFOT]:RotateAroundAxis( ang[LFOT]:Up(), 90 )
ang[LFOT]:RotateAroundAxis( ang[LFOT]:Forward(), -45 )
ang[RFOT]:RotateAroundAxis( ang[LFOT]:Forward(), -45 )
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
ang[NECK] = ang[HEAD]
pos[16] = pos[PLVS]
ang[16] = ang[PLVS] * 1
ang[16]:RotateAroundAxis( ang[1]:Right(), 180 )
--
-- AGH HANDS
--
ang[LHND] = ang[LARM] * 1
ang[LHND]:RotateAroundAxis( ang[LHND]:Up(), 90 )
ang[RHND] = ang[RARM] * 1
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/sniper.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/sniper.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/sniper/bot_sniper.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_sniper", Builder )

View File

@@ -0,0 +1,154 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local RTHY = 1
local RCLF = 2
local LTHY = 3
local LCLF = 4
local LFOT = 5
local SPNE = 6
local TRSO = 7
local RSLD = 8
local LSLD = 9
local LARM = 10
local LHND = 11
local RARM = 12
local NECK = 13
local RHND = 14
local HEAD = 15
local RFOT = 16
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.8
local acrossshoulders = ( sensor[SENSORBONE.SHOULDER_RIGHT] - sensor[SENSORBONE.SHOULDER_LEFT] ):GetNormal() * 0.08
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch - acrossshoulders )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch + acrossshoulders )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.8 )
local acrosships = ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.HIP_RIGHT] ):GetNormal() * 0.08
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * -0.1 + acrosships )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * -0.1 + acrosships * -1 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.KNEE_LEFT]-sensor[SENSORBONE.HIP_LEFT] ) * 0.3 + acrosships )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.KNEE_RIGHT] - sensor[SENSORBONE.HIP_RIGHT] ) * 0.3 - acrosships )
sensor[SENSORBONE.ANKLE_LEFT]:Add( ( sensor[SENSORBONE.ANKLE_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.8 + acrosships )
sensor[SENSORBONE.ANKLE_RIGHT]:Add( ( sensor[SENSORBONE.ANKLE_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.8 - acrosships )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[TRSO] = { type = "lerp", value = 0.2, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE },
[NECK] = { type = "lerp", value = 0.3, from = SENSORBONE.SHOULDER, to = SENSORBONE.HEAD },
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = { type = "lerp", value = 0.8, from = SENSORBONE.SHOULDER, to = SENSORBONE.SPINE }
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = PLVS, to = SPNE, up = "hips_back" },
[SPNE] = { from = SPNE, to = TRSO, up = "chest_bck" },
[TRSO] = { from = TRSO, to = NECK, up = "head_back" },
[HEAD] = { from = NECK, to = HEAD, up = "head_back" },
[NECK] = { from = TRSO, to = NECK, up = "head_back" },
[RSLD] = { from = RARM, to = RSLD, up_rgt = TRSO },
[RARM] = { from = RHND, to = RARM, up_up = RSLD },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_dn = RARM },
[LSLD] = { from = LARM, to = LSLD, up_lft = TRSO },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[LHND] = { from_sensor = SENSORBONE.WRIST_LEFT, to_sensor = SENSORBONE.HAND_LEFT, up_up = LARM },
[RTHY] = { from = RCLF, to = RTHY, up = "right" },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up = "forward" },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
--
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
--
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 0, 90, -70 )
ang[LFOT] = ang[LCLF]:Right():AngleEx( ang[LCLF]:Up() ) + Angle( 0, -90, 110 )
--
-- TODO: Get the hands working.
--
--ang[RHND] = ( ang[RARM]:Up() ):AngleEx( ang[RARM]:Right() * -1 )
--ang[LHND] = ( ang[LARM]:Up() ):AngleEx( ang[LARM]:Right() )
--
-- Maya uses Y up for some bones. Because life isn't hard enough already.
--
ang[PLVS]:RotateAroundAxis( ang[PLVS]:Up(), -90 )
ang[SPNE]:RotateAroundAxis( ang[SPNE]:Up(), -90 )
ang[TRSO]:RotateAroundAxis( ang[TRSO]:Up(), -90 )
ang[NECK]:RotateAroundAxis( ang[NECK]:Up(), -90 )
ang[HEAD]:RotateAroundAxis( ang[HEAD]:Up(), -90 )
ang[LHND]:RotateAroundAxis( ang[LHND]:Up(), -90 )
ang[RHND]:RotateAroundAxis( ang[RHND]:Up(), -90 )
--ang[LHND]:RotateAroundAxis( ang[LHND]:Right(), 180 )
end,
IsApplicable = function( self, ent )
local mdl = ent:GetModel()
if ( mdl:EndsWith( "models/player/hwm/soldier.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/soldier.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/spy.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/player/hwm/spy.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/soldier/bot_soldier.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/spy/bot_spy.mdl" ) ) then return true end
if ( mdl:EndsWith( "models/bots/soldier_boss/bot_soldier_boss.mdl" ) ) then return true end
return false
end,
}
list.Set( "SkeletonConvertor", "TF2_soldier_spy", Builder )

View File

@@ -0,0 +1,104 @@
--
-- These are the physics bone numbers
--
local PLVS = 0
local SPNE = 1
local RSLD = 2
local LSLD = 3
local LARM = 4
local LHND = 5
local RARM = 6
local RHND = 7
local RTHY = 8
local RCLF = 9
local HEAD = 10
local LTHY = 11
local LCLF = 12
local LFOT = 13
local RFOT = 14
local Builder =
{
PrePosition = function( self, sensor )
local spinestretch = ( sensor[SENSORBONE.SHOULDER] - sensor[SENSORBONE.SPINE] ) * 0.7
sensor[SENSORBONE.SHOULDER]:Add( spinestretch * 0.7 )
sensor[SENSORBONE.SHOULDER_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.SHOULDER_LEFT]:Add( spinestretch )
sensor[SENSORBONE.ELBOW_LEFT]:Add( spinestretch )
sensor[SENSORBONE.ELBOW_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.WRIST_LEFT]:Add( spinestretch )
sensor[SENSORBONE.WRIST_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.HAND_LEFT]:Add( spinestretch )
sensor[SENSORBONE.HAND_RIGHT]:Add( spinestretch )
sensor[SENSORBONE.HEAD]:Add( spinestretch * 0.5 )
sensor[SENSORBONE.HIP_LEFT]:Add( spinestretch * 0.3 )
sensor[SENSORBONE.HIP_RIGHT]:Add( spinestretch * 0.3 )
sensor[SENSORBONE.KNEE_RIGHT]:Add( ( sensor[SENSORBONE.HIP_RIGHT] - sensor[SENSORBONE.KNEE_RIGHT] ) * 0.2 )
sensor[SENSORBONE.KNEE_LEFT]:Add( ( sensor[SENSORBONE.HIP_LEFT] - sensor[SENSORBONE.KNEE_LEFT] ) * 0.2 )
end,
--
-- Which on the sensor should we use for which ones on our model
--
PositionTable =
{
[PLVS] = SENSORBONE.HIP,
[RSLD] = SENSORBONE.SHOULDER_RIGHT,
[LSLD] = SENSORBONE.SHOULDER_LEFT,
[LARM] = SENSORBONE.ELBOW_LEFT,
[LHND] = SENSORBONE.WRIST_LEFT,
[RARM] = SENSORBONE.ELBOW_RIGHT,
[RHND] = SENSORBONE.WRIST_RIGHT,
[LTHY] = SENSORBONE.HIP_LEFT,
[RTHY] = SENSORBONE.HIP_RIGHT,
[RCLF] = SENSORBONE.KNEE_RIGHT,
[LCLF] = SENSORBONE.KNEE_LEFT,
[RFOT] = SENSORBONE.ANKLE_RIGHT,
[LFOT] = SENSORBONE.ANKLE_LEFT,
[HEAD] = SENSORBONE.HEAD,
[SPNE] = SENSORBONE.SPINE,
},
--
-- Which bones should we use to determine our bone angles
--
AnglesTable =
{
[PLVS] = { from = LTHY, to = RTHY, up = "hips_fwd" },
[SPNE] = { from_sensor = SENSORBONE.HEAD, to_sensor = SENSORBONE.SPINE, up = "chest_rgt" },
[HEAD] = { from_sensor = SENSORBONE.HEAD, to_sensor = SENSORBONE.SHOULDER, up = "chest_lft" },
[RSLD] = { from = RARM, to = RSLD, up = "chest_up" },
[LSLD] = { from = LARM, to = LSLD, up = "chest_dn" },
[RARM] = { from = RHND, to = RARM, up_up = RSLD },
[LARM] = { from = LHND, to = LARM, up_up = LSLD },
[RTHY] = { from = RCLF, to = RTHY, up_up = SPNE },
[RCLF] = { from = RFOT, to = RCLF, up_up = RTHY },
[LTHY] = { from = LCLF, to = LTHY, up_up = SPNE },
[LCLF] = { from = LFOT, to = LCLF, up_up = LTHY },
[RHND] = { from_sensor = SENSORBONE.HAND_RIGHT, to_sensor = SENSORBONE.WRIST_RIGHT, up_lft = RARM },
[LHND] = { from_sensor = SENSORBONE.HAND_LEFT, to_sensor = SENSORBONE.WRIST_LEFT, up_rgt = LARM }
},
--
-- Any polishing that can't be done with the above tables
--
Complete = function( self, player, sensor, rotation, pos, ang )
pos[SPNE] = LerpVector( 0.45, pos[SPNE], pos[HEAD] )
-- Feet are insanely spazzy, so we lock the feet to the angle of the calf
ang[LFOT] = ang[LCLF]:Right():AngleEx( ang[LCLF]:Up() ) + Angle( 20, 0, 0 )
ang[RFOT] = ang[RCLF]:Right():AngleEx( ang[RCLF]:Up() ) + Angle( 20, 0, 0 )
end,
-- We're used as a default - no need to return true to anything here.
IsApplicable = function( self, ent ) return false end,
}
list.Set( "SkeletonConvertor", "ValveBiped", Builder )

View File

@@ -0,0 +1,11 @@
resource.AddWorkshop("2486994157") -- Mac Quests
resource.AddWorkshop("2973776853") -- QWB
resource.AddWorkshop("1912375404") -- Map
resource.AddWorkshop("2844924488") -- Senwai
resource.AddWorkshop("3626176147") -- Event content
for i,addon in pairs( engine.GetAddons() ) do
if addon.mounted then
resource.AddWorkshop(addon.wsid)
--print("\t[+] "..addon.wsid..": "..addon.title)
end
end

View File

@@ -0,0 +1,269 @@
--
-- The server only runs this file so it can send it to the client
--
if ( SERVER ) then AddCSLuaFile( "utilities_menu.lua" ) return end
local function Undo( pnl )
-- This is added by the undo module dynamically
end
local function User_Cleanup( pnl )
-- This is added by the cleanup module dynamically
end
local function LoadInConvarDefaults( cvars )
for k, v in pairs( cvars ) do
local convar = GetConVar( k )
if ( convar and convar:GetDefault():len() != 0 ) then
cvars[ k ] = convar:GetDefault()
end
end
end
local function ServerSettings( pnl )
pnl:Help( "#utilities.serversettings" )
local ConVarsDefault = {
hostname = "My Garry's Mod Server",
-- sv_password = "", -- Can't be read by addons/servers
sv_kickerrornum = "0",
sv_allowcslua = "0",
sv_sticktoground = "1",
sv_playerpickupallowed = "1",
mp_falldamage = "0",
gmod_suit = "0",
gmod_maxammo = "9999",
sv_gravity = "600",
sv_friction = "8",
phys_timescale = "1.00",
gmod_physiterations = "4",
sv_defaultdeployspeed = "4.00",
sv_noclipspeed = "5",
g_ragdoll_maxcount = "32",
sv_timeout = "65"
}
LoadInConvarDefaults( ConVarsDefault )
pnl:ToolPresets( "util_server", ConVarsDefault )
pnl:TextEntry( "#utilities.hostname", "hostname" )
pnl:TextEntry( "#utilities.password", "sv_password" )
pnl:CheckBox( "#utilities.kickerrornum", "sv_kickerrornum" )
pnl:CheckBox( "#utilities.allowcslua", "sv_allowcslua" )
pnl:CheckBox( "#utilities.sticktoground", "sv_sticktoground" )
pnl:ControlHelp( "#utilities.sticktoground.help" ):DockMargin( 32, 4, 32, 8 ) -- 4 extra on top
pnl:CheckBox( "#utilities.epickupallowed", "sv_playerpickupallowed" )
pnl:CheckBox( "#utilities.falldamage", "mp_falldamage" )
pnl:CheckBox( "#utilities.gmod_suit", "gmod_suit" )
-- Fun convars
pnl:NumSlider( "#utilities.gravity", "sv_gravity", -500, 1000, 0 )
pnl:NumSlider( "#utilities.friction", "sv_friction", 0, 16, 0 )
pnl:NumSlider( "#utilities.timescale", "phys_timescale", 0, 2 )
pnl:NumSlider( "#utilities.deployspeed", "sv_defaultdeployspeed", 0.1, 10 )
pnl:NumSlider( "#utilities.noclipspeed", "sv_noclipspeed", 1, 10, 0 ) -- TODO: Switch this and friction back to Float once the sliders dont reset the convar from 8 to 8.00
pnl:NumSlider( "#utilities.maxammo", "gmod_maxammo", 0, 9999, 0 )
pnl:ControlHelp( "#utilities.maxammo.help" )
pnl:NumSlider( "#utilities.max_ragdolls", "g_ragdoll_maxcount", 0, 128, 0 )
-- Technical convars
pnl:NumSlider( "#utilities.iterations", "gmod_physiterations", 1, 10, 0 )
pnl:NumSlider( "#utilities.sv_timeout", "sv_timeout", 60, 300, 0 )
end
local function SandboxClientSettings( pnl )
pnl:Help( "#utilities.sandboxsettings_cl" )
local ConVarsDefault = {
sbox_search_maxresults = "1024",
cl_drawhud = "1",
gmod_drawhelp = "1",
gmod_drawtooleffects = "1",
cl_drawworldtooltips = "1",
cl_drawspawneffect = "1",
cl_draweffectrings = "1",
cl_drawcameras = "1",
cl_drawthrusterseffects = "1",
cl_showhints = "1",
spawnmenu_toggle = "0",
}
LoadInConvarDefaults( ConVarsDefault )
pnl:ToolPresets( "util_sandbox_cl", ConVarsDefault )
pnl:NumSlider( "#utilities.max_results", "sbox_search_maxresults", 1024, 8192, 0 )
pnl:ControlHelp( "#utilities.max_results.help" )
pnl:CheckBox( "#menubar.drawing.hud", "cl_drawhud" )
pnl:CheckBox( "#menubar.drawing.toolhelp", "gmod_drawhelp" )
pnl:CheckBox( "#menubar.drawing.toolui", "gmod_drawtooleffects" )
pnl:CheckBox( "#menubar.drawing.world_tooltips", "cl_drawworldtooltips" )
pnl:CheckBox( "#menubar.drawing.spawn_effect", "cl_drawspawneffect" )
pnl:CheckBox( "#menubar.drawing.effect_rings", "cl_draweffectrings" )
pnl:CheckBox( "#menubar.drawing.cameras", "cl_drawcameras" )
pnl:CheckBox( "#menubar.drawing.thrusters", "cl_drawthrusterseffects" )
pnl:CheckBox( "#menubar.drawing.hints", "cl_showhints" )
pnl:CheckBox( "#utilities.spawnmenu_toggle", "spawnmenu_toggle" )
pnl:ControlHelp( "#utilities.spawnmenu_toggle.help" ):DockMargin( 32, 4, 32, 8 ) -- 4 extra on top
end
local function SandboxSettings( pnl )
pnl:Help( "#utilities.sandboxsettings" )
local ConVarsDefault = {
sbox_persist = "",
sbox_noclip = "1",
sbox_weapons = "1",
sbox_godmode = "0",
sbox_playershurtplayers = "1",
physgun_limited = "0",
physgun_maxrange = "4096",
sbox_bonemanip_npc = "1",
sbox_bonemanip_player = "0",
sbox_bonemanip_misc = "0"
}
LoadInConvarDefaults( ConVarsDefault )
local ConVarsLimits = {}
for id, str in pairs( cleanup.GetTable() ) do
local cvar = GetConVar( "sbox_max" .. str )
if ( !cvar ) then continue end
ConVarsDefault[ "sbox_max" .. str ] = cvar:GetDefault()
table.insert( ConVarsLimits, {
command = "sbox_max" .. str,
default = cvar:GetDefault(),
label = language.GetPhrase( "max_" .. str ),
min = 0,
max = math.max( 200, cvar:GetDefault() * 1.4 )
} )
end
pnl:ToolPresets( "util_sandbox", ConVarsDefault )
pnl:TextEntry( "#persistent_mode", "sbox_persist" )
pnl:ControlHelp( "#persistent_mode.help" ):DockMargin( 16, 4, 16, 8 )
pnl:CheckBox( "#enable_weapons", "sbox_weapons" )
pnl:CheckBox( "#allow_god_mode", "sbox_godmode" )
pnl:ControlHelp( "#utilities.mp_only" ):DockMargin( 16, 16, 16, 4 )
pnl:CheckBox( "#players_damage_players", "sbox_playershurtplayers" )
pnl:CheckBox( "#allow_noclip", "sbox_noclip" )
pnl:CheckBox( "#bone_manipulate_npcs", "sbox_bonemanip_npc" )
pnl:CheckBox( "#bone_manipulate_players", "sbox_bonemanip_player" )
pnl:CheckBox( "#bone_manipulate_others", "sbox_bonemanip_misc" )
for id, t in SortedPairsByMemberValue( ConVarsLimits, "label" ) do
pnl:NumSlider( t.label, t.command, t.min, t.max, 0 ):SetHeight( 16 ) -- This makes the controls all bunched up like how we want
end
end
local function PhysgunSettings( pnl )
pnl:Help( "#utilities.physgunsettings" )
local ConVarsDefault = {
physgun_halo = "1",
physgun_drawbeams = "1",
effects_freeze = "1",
effects_unfreeze = "1",
gm_snapgrid = "0",
gm_snapangles = "45",
physgun_rotation_sensitivity = "0.05",
physgun_wheelspeed = "10"
}
LoadInConvarDefaults( ConVarsDefault )
pnl:ToolPresets( "util_physgun", ConVarsDefault )
pnl:CheckBox( "#utilities.physgun_halo", "physgun_halo" )
pnl:CheckBox( "#utilities.physgun_drawbeams", "physgun_drawbeams" )
pnl:CheckBox( "#menubar.drawing.freeze", "effects_freeze" )
pnl:CheckBox( "#menubar.drawing.unfreeze", "effects_unfreeze" )
pnl:NumSlider( "#utilities.gm_snapgrid", "gm_snapgrid", 0, 128, 0 )
pnl:NumSlider( "#utilities.gm_snapangles", "gm_snapangles", 5, 90, 0 )
pnl:NumSlider( "#utilities.physgun_rotation_sensitivity", "physgun_rotation_sensitivity", 0.01, 1, 2 )
pnl:NumSlider( "#utilities.physgun_wheelspeed", "physgun_wheelspeed", 0, 50, 0 )
end
local function PhysgunSVSettings( pnl )
pnl:Help( "#utilities.physgunsvsettings" )
local ConVarsDefault = {
physgun_limited = "0",
physgun_maxrange = "4096",
physgun_teleportDistance = "0",
physgun_maxSpeed = "5000",
physgun_maxAngular = "5000",
physgun_timeToArrive = "0.05",
physgun_timeToArriveRagdoll = "0.1"
}
LoadInConvarDefaults( ConVarsDefault )
pnl:ToolPresets( "util_physgun_sv", ConVarsDefault )
pnl:CheckBox( "#utilities.physgun_limited", "physgun_limited" )
pnl:ControlHelp( "#utilities.physgun_limited.help" ):DockMargin( 32, 4, 32, 8 ) -- 4 extra on top
pnl:NumSlider( "#utilities.physgun_maxrange", "physgun_maxrange", 128, 8192, 0 )
pnl:NumSlider( "#utilities.physgun_tpdist", "physgun_teleportdistance", 0, 10000, 0 )
pnl:NumSlider( "#utilities.physgun_maxspeed", "physgun_maxspeed", 0, 10000, 0 )
pnl:NumSlider( "#utilities.physgun_maxangular", "physgun_maxangular", 0, 10000, 0 )
pnl:NumSlider( "#utilities.physgun_timetoarrive", "physgun_timetoarrive", 0, 2, 2 )
pnl:NumSlider( "#utilities.physgun_timetoarriveragdoll", "physgun_timetoarriveragdoll", 0, 2, 2 )
pnl:ControlHelp( "#utilities.physgun_timetoarriveragdoll.help" )
end
local function PlayerOptions( pnl )
pnl:Help( "#smwidget.playermodel_title" )
pnl:Button( "#smwidget.playermodel_title", "open_playermodel_selector" )
end
-- Tool Menu
hook.Add( "PopulateToolMenu", "PopulateUtilityMenus", function()
spawnmenu.AddToolMenuOption( "Utilities", "User", "User_Cleanup", "#spawnmenu.utilities.cleanup", "", "", User_Cleanup )
spawnmenu.AddToolMenuOption( "Utilities", "User", "Undo", "#spawnmenu.utilities.undo", "", "", Undo )
spawnmenu.AddToolMenuOption( "Utilities", "User", "PhysgunSettings", "#spawnmenu.utilities.physgunsettings", "", "", PhysgunSettings )
spawnmenu.AddToolMenuOption( "Utilities", "User", "SandboxClientSettings", "#spawnmenu.utilities.sandbox_settings", "", "", SandboxClientSettings )
spawnmenu.AddToolMenuOption( "Utilities", "User", "PlayerModelSelector", "#smwidget.playermodel_title", "", "", PlayerOptions )
spawnmenu.AddToolMenuOption( "Utilities", "Admin", "Admin_Cleanup", "#spawnmenu.utilities.cleanup", "", "", User_Cleanup )
spawnmenu.AddToolMenuOption( "Utilities", "Admin", "ServerSettings", "#spawnmenu.utilities.server_settings", "", "", ServerSettings )
spawnmenu.AddToolMenuOption( "Utilities", "Admin", "SandboxSettings", "#spawnmenu.utilities.sandbox_settings", "", "", SandboxSettings )
spawnmenu.AddToolMenuOption( "Utilities", "Admin", "PhysgunSVSettings", "#spawnmenu.utilities.physgunsettings", "", "", PhysgunSVSettings )
end )
-- Categories
hook.Add( "AddToolMenuCategories", "CreateUtilitiesCategories", function()
spawnmenu.AddToolCategory( "Utilities", "User", "#spawnmenu.utilities.user" )
spawnmenu.AddToolCategory( "Utilities", "Admin", "#spawnmenu.utilities.admin" )
end )