Compare commits
	
		
			36 Commits 
		
	
	
		
			v0.2-alpha
			...
			master
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 3b0dc2f4a9 | |
|  | 3b67b8d125 | |
|  | 01dbe8f68f | |
|  | bf8df06323 | |
|  | b4f17cac01 | |
|  | 10fe1e17c1 | |
|  | 736318a730 | |
|  | 25f9767509 | |
|  | 3aaf4a4e7b | |
|  | 963598b7d1 | |
|  | d463542883 | |
|  | 2cf2fbe95a | |
|  | 0d59d285d1 | |
|  | 901b76e8d9 | |
|  | 142c0a2f18 | |
|  | 1799760eab | |
|  | f65cc5fb03 | |
|  | fba811e125 | |
|  | fc671ec6b6 | |
|  | c8a3a64d38 | |
|  | d23af759d5 | |
|  | 64428b54ef | |
|  | 744a73a3c3 | |
|  | e05231b293 | |
|  | 2772c9905a | |
|  | 1ab7c74f9a | |
|  | 6c636543ad | |
|  | dde7e30d6d | |
|  | 116aeddef4 | |
|  | ed9de4d416 | |
|  | a3492505ac | |
|  | 3a64efe6c9 | |
|  | e895aff152 | |
|  | 91c4630abc | |
|  | 72f305e004 | |
|  | 6104749c32 | 
|  | @ -2,6 +2,7 @@ | ||||||
| ## GMA compile output | ## GMA compile output | ||||||
| ###################### | ###################### | ||||||
| tmp/ | tmp/ | ||||||
|  | builds/ | ||||||
| *.gma | *.gma | ||||||
| 
 | 
 | ||||||
| ############# | ############# | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | [submodule "tools/luasrcdiet"] | ||||||
|  | 	path = tools/luasrcdiet | ||||||
|  | 	url = https://github.com/LuaDist/luasrcdiet | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| Disguiser SWEP | Disguiser SWEP | ||||||
| ============== | ============== | ||||||
| 
 | 
 | ||||||
|  | [![YouTube: [gmod] Derping around with the Disguiser ](http://img.youtube.com/vi/IvMkNIm4Ro0/0.jpg)](http://www.youtube.com/watch?v=IvMkNIm4Ro0&feature=github) | ||||||
|  | 
 | ||||||
| So you always wanted to be able to disguise as another item on the map in Sandbox or | So you always wanted to be able to disguise as another item on the map in Sandbox or | ||||||
| any other game mode than Prop Hunt? You were always annoyed by how you were able to | any other game mode than Prop Hunt? You were always annoyed by how you were able to | ||||||
| see yourself being able to rotate but without knowing you were still standing all the | see yourself being able to rotate but without knowing you were still standing all the | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								TODO.md
								
								
								
								
							
							
						
						
									
										4
									
								
								TODO.md
								
								
								
								
							|  | @ -1,8 +1,5 @@ | ||||||
| # Bugs | # Bugs | ||||||
| 
 | 
 | ||||||
| - (Severe) Can use non-studio models (example: *3) |  | ||||||
| 	=> Segmentation fault cause |  | ||||||
| 
 |  | ||||||
| # Optional fixes | # Optional fixes | ||||||
| 
 | 
 | ||||||
| - Item on cs_office needs correction (Which one, lol?) | - Item on cs_office needs correction (Which one, lol?) | ||||||
|  | @ -11,3 +8,4 @@ | ||||||
| 
 | 
 | ||||||
| - Configuration via console vars | - Configuration via console vars | ||||||
| - Configuration via menusystem | - Configuration via menusystem | ||||||
|  | - Move this TODO list completely to GitHub's issue tracker | ||||||
|  |  | ||||||
|  | @ -0,0 +1,16 @@ | ||||||
|  | { | ||||||
|  | 	"title"		:	"Disguiser SWEP", | ||||||
|  | 	"type"		:	"weapon", | ||||||
|  | 	"tags"		:	[ "fun", "comic" ], | ||||||
|  | 	"ignore"	: | ||||||
|  | 	[ | ||||||
|  | 		"*.git*", | ||||||
|  | 		"*.svn*", | ||||||
|  | 		"builds*", | ||||||
|  | 		"tools*", | ||||||
|  | 		"*.bat", | ||||||
|  | 		"*.sh", | ||||||
|  | 		"*.md", | ||||||
|  | 		"LICENSE.txt" | ||||||
|  | 	] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,75 @@ | ||||||
|  | @echo off & setlocal enabledelayedexpansion | ||||||
|  | 
 | ||||||
|  | path %programfiles(x86)%\lua\5.1\;%path%;%programfiles(x86)%\Steam\SteamApps\common\GarrysMod\bin | ||||||
|  | 
 | ||||||
|  | if not exist builds mkdir builds | ||||||
|  | mkdir tmp | ||||||
|  | 
 | ||||||
|  | :: Root path | ||||||
|  | set workspace=%cd% | ||||||
|  | set workspacelentmp=%workspace% | ||||||
|  | set workspacelen=1 | ||||||
|  | :workspacelencalc | ||||||
|  | set /a workspacelen=!workspacelen!+1 | ||||||
|  | set workspace=!workspace:~1! | ||||||
|  | if "%workspace%"=="" goto compile | ||||||
|  | goto workspacelencalc | ||||||
|  | 
 | ||||||
|  | :compileerr | ||||||
|  | echo ERROR: Compilation failed. | ||||||
|  | exit /B -1 | ||||||
|  | 
 | ||||||
|  | :compile | ||||||
|  | echo Workspace: %workspace% (%workspacelen%) | ||||||
|  | :: Compile LUA files | ||||||
|  | pushd lua | ||||||
|  | for /r %%i in (.) do ( | ||||||
|  | 	set absdir=%%i | ||||||
|  | 	set directory=!absdir:~%workspacelen%,-2! | ||||||
|  | 
 | ||||||
|  | 	echo Creating !directory!... | ||||||
|  | 	mkdir "..\tmp\!directory!" | ||||||
|  | ) | ||||||
|  | for /r %%i in (*.lua) do ( | ||||||
|  | 	set absfile=%%i | ||||||
|  | 	set file=!absfile:~%workspacelen%! | ||||||
|  | 
 | ||||||
|  | 	echo Compiling !file!... | ||||||
|  | 	luac52 -o "..\tmp\!file!" "!absfile!" | ||||||
|  | 	if %errorlevel% NEQ 0 ( | ||||||
|  | 		echo Could not compile !file!, only copying... | ||||||
|  | 		copy !absfile! "..\tmp\!file!" | ||||||
|  | 	) | ||||||
|  | ) | ||||||
|  | popd | ||||||
|  | 
 | ||||||
|  | :: Optimize LUA files | ||||||
|  | ::set cutofflen= | ||||||
|  | ::set foo=%~dp0 | ||||||
|  | :::_cl1 | ||||||
|  | ::if not "!foo!"=="" ( | ||||||
|  | ::	set /a cutofflen += 1 | ||||||
|  | ::	set foo=!foo:~1! | ||||||
|  | ::	goto _cl1 | ||||||
|  | ::) | ||||||
|  | ::for /R lua %%f in (*.lua) do ( | ||||||
|  | ::	set B=%%~ff | ||||||
|  | ::	set B=!B:~%cutofflen%! | ||||||
|  | ::	if not exist "!~dpB!" ( | ||||||
|  | ::		mkdir "!~dpB!" | ||||||
|  | ::	) | ||||||
|  | ::	echo Optimizing: !B! | ||||||
|  | ::	pushd tools\luasrcdiet | ||||||
|  | ::	LuaSrcDiet.lua ..\..\!B! --quiet -o ..\..\tmp\!B! | ||||||
|  | ::	popd | ||||||
|  | ::) | ||||||
|  | 
 | ||||||
|  | :: Copy over resources | ||||||
|  | robocopy . tmp *.json *.lua *.wav *.mp3 *.jpg *.png *.txt /MIR /XD tools /XD tmp /XF LICENSE.txt /NJH /NJS /NDL /NP /NS | ||||||
|  | 
 | ||||||
|  | :: Create the GMA file | ||||||
|  | gmad create -folder "tmp" -out "builds\disguiser_swep.gma" | ||||||
|  | 
 | ||||||
|  | :: Clean up | ||||||
|  | rmdir /q /s tmp | ||||||
|  | ::pause | ||||||
|  | @ -0,0 +1,99 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | reldir() { | ||||||
|  | 	# both $1 and $2 are absolute paths beginning with / | ||||||
|  | 	# returns relative path to $2/$target from $1/$source | ||||||
|  | 	source=$1 | ||||||
|  | 	target=$2 | ||||||
|  | 
 | ||||||
|  | 	common_part=$source # for now | ||||||
|  | 	result="" # for now | ||||||
|  | 
 | ||||||
|  | 	while [[ "${target#$common_part}" == "${target}" ]]; do | ||||||
|  | 	    # no match, means that candidate common part is not correct | ||||||
|  | 	    # go up one level (reduce common part) | ||||||
|  | 	    common_part="$(dirname $common_part)" | ||||||
|  | 	    # and record that we went back, with correct / handling | ||||||
|  | 	    if [[ -z $result ]]; then | ||||||
|  | 	        result=".." | ||||||
|  | 	    else | ||||||
|  | 	        result="../$result" | ||||||
|  | 	    fi | ||||||
|  | 	done | ||||||
|  | 
 | ||||||
|  | 	if [[ $common_part == "/" ]]; then | ||||||
|  | 	    # special case for root (no common path) | ||||||
|  | 	    result="$result/" | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	# since we now have identified the common part, | ||||||
|  | 	# compute the non-common part | ||||||
|  | 	forward_part="${target#$common_part}" | ||||||
|  | 
 | ||||||
|  | 	# and now stick all parts together | ||||||
|  | 	if [[ -n $result ]] && [[ -n $forward_part ]]; then | ||||||
|  | 	    result="$result$forward_part" | ||||||
|  | 	elif [[ -n $forward_part ]]; then | ||||||
|  | 	    # extra slash removal | ||||||
|  | 	    result="${forward_part:1}" | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	echo $result | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | copy_flt() { | ||||||
|  | 	filter="$3" | ||||||
|  | 	source="$1" | ||||||
|  | 	target="$2" | ||||||
|  | 
 | ||||||
|  | 	find "$source" -type "d" -not -path "$target" | while read i; do | ||||||
|  | 		mkdir -p "$target/$(reldir $source $i)" | ||||||
|  | 	done | ||||||
|  | 	find "$source" -name "$filter" -type "f" -not -path "$target" | while read i; do | ||||||
|  | 		cp "$i" "$target/$(reldir $source $i)" | ||||||
|  | 	done | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | mkdir -p builds | ||||||
|  | 
 | ||||||
|  | if [ -e tmp ]; then | ||||||
|  | 	rm -rf tmp | ||||||
|  | fi | ||||||
|  | mkdir -p tmp | ||||||
|  | 
 | ||||||
|  | # Root path | ||||||
|  | workspace=$(pwd) | ||||||
|  | 
 | ||||||
|  | echo Workspace: $workspace | ||||||
|  | 
 | ||||||
|  | # Copy over | ||||||
|  | copy_flt "." "tmp" "*.json" | ||||||
|  | copy_flt "." "tmp" "*.wav" | ||||||
|  | copy_flt "." "tmp" "*.lua" | ||||||
|  | copy_flt "." "tmp" "*.mp3" | ||||||
|  | copy_flt "." "tmp" "*.jpg" | ||||||
|  | copy_flt "." "tmp" "*.png" | ||||||
|  | copy_flt "." "tmp" "*.txt" | ||||||
|  | 
 | ||||||
|  | find tmp | ||||||
|  | 
 | ||||||
|  | # Compile LUA files | ||||||
|  | pushd lua | ||||||
|  | mkdir -p ../tmp/lua | ||||||
|  | find . -type f -name '*.lua' | while read absfile; do | ||||||
|  | 	file="lua/$absfile" | ||||||
|  | 	echo "Compiling $file..." | ||||||
|  | 	luac5.2 -o "../tmp/$file.luac" "$absfile" && ( | ||||||
|  | 		rm "/tmp/$file" | ||||||
|  | 		mv "/tmp/$file.luac" "/tmp/$file" | ||||||
|  | 	) || ( | ||||||
|  | 		echo "Could not compile $file, leaving as is." | ||||||
|  | 	) | ||||||
|  | done | ||||||
|  | popd | ||||||
|  | 
 | ||||||
|  | # Create the GMA file | ||||||
|  | gmad create -warninvalid -folder "tmp" -out "builds/disguiser_swep.gma" | ||||||
|  | 
 | ||||||
|  | # Clean up | ||||||
|  | rm -rf tmp | ||||||
|  | @ -1,48 +1,47 @@ | ||||||
| /** | -- | ||||||
|  * Disguiser SWEP - Lets you disguise as any prop on a map. | -- Disguiser SWEP - Lets you disguise as any prop on a map. | ||||||
|  * | -- | ||||||
|  * File: | -- File: | ||||||
|  *   patch_createfont.lua | --   patch_createfont.lua | ||||||
|  * | -- | ||||||
|  * Purpose: | -- Purpose: | ||||||
|  *   This code will allow any font to be checked for existence. I hope it works | --   This code will allow any font to be checked for existence. I hope it works | ||||||
|  *   as it is only a function patch which should be loaded right at the beginning. | --   as it is only a function patch which should be loaded right at the beginning. | ||||||
|  *   Can't guarantee that it loads right at the beginning though. | --   Can't guarantee that it loads right at the beginning though. | ||||||
|  * | -- | ||||||
|  * Copyright (C) 2013 Carl Kittelberger (Icedream) | -- Copyright (C) 2013 Carl Kittelberger (Icedream) | ||||||
|  * | -- | ||||||
|  * This program is free software: you can redistribute it and/or modify | -- This program is free software: you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU Affero General Public License as | -- it under the terms of the GNU Affero General Public License as | ||||||
|  * published by the Free Software Foundation, either version 3 of the | -- published by the Free Software Foundation, either version 3 of the | ||||||
|  * License, or (at your option) any later version. | -- License, or (at your option) any later version. | ||||||
|  * | -- | ||||||
|  * This program is distributed in the hope that it will be useful, | -- This program is distributed in the hope that it will be useful, | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  * GNU Affero General Public License for more details. | -- GNU Affero General Public License for more details. | ||||||
|  * | -- | ||||||
|  * You should have received a copy of the GNU Affero General Public License | -- You should have received a copy of the GNU Affero General Public License | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | -- along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  | ||||||
| 
 | 
 | ||||||
| print("[Disguiser] Loading compatibility layer for surface.CreateFont...") | print("[Disguiser] Loading compatibility layer for surface.CreateFont...") | ||||||
| 
 | 
 | ||||||
| local registered_fonts = {} | local registered_fonts = {} | ||||||
| 
 | 
 | ||||||
| // Function already patched by us? | -- Function already patched by us? | ||||||
| if !!surface.__createFont then | if not surface.__createFont == nil then | ||||||
| 	MsgC(Color(255, 255, 0), "[Fontpatch] Can't patch surface.CreateFont, already patched. Skipping patch.\n") | 	MsgC(Color(255, 255, 0), "[Fontpatch] Can't patch surface.CreateFont, already patched. Skipping patch.\n") | ||||||
| 	return | 	return | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| // Original function | -- Original function | ||||||
| surface.__createFont = surface.CreateFont | surface.__createFont = surface.CreateFont | ||||||
| 
 | 
 | ||||||
| // Patch function | -- Patch function | ||||||
| function surface.CreateFont(name, data) | function surface.CreateFont(name, data) | ||||||
| 	if !name || !data then return false end | 	if not name or not data then return false end | ||||||
| 
 | 
 | ||||||
| 	if !!registered_fonts[name] then | 	if registered_fonts[name] then | ||||||
| 		MsgN("[Fontpatch] Skipping font " .. name .. ", already registered") | 		MsgN("[Fontpatch] Skipping font " .. name .. ", already registered") | ||||||
| 	else | 	else | ||||||
| 		MsgN("[Fontpatch] Registering font " .. name .. "...") | 		MsgN("[Fontpatch] Registering font " .. name .. "...") | ||||||
|  | @ -51,7 +50,7 @@ function surface.CreateFont(name, data) | ||||||
| 	surface.__createFont(name, data) | 	surface.__createFont(name, data) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| // Check if a font exists | -- Check if a font exists | ||||||
| function surface.FontExists(name) | function surface.FontExists(name) | ||||||
| 	return !!registered_fonts[name] // I love how all those peeps on the internet still don't use the !! thingie | 	return not not registered_fonts[name] | ||||||
| end | end | ||||||
|  | @ -27,34 +27,37 @@ | ||||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| hook.Add("CalcView", "Disguiser.ThirdPersonCalcView", function(player, pos, angles, fov) | hook.Add("CalcView", "Disguiser.ThirdPersonCalcView", function(ply, pos, angles, fov) | ||||||
| 	local smoothscale = 1 | 	smoothscale = 1 | ||||||
| 	 | 	 | ||||||
| 	if player:GetNetworkedBool("thirdperson") then | 	if IsValid(ply) && ply:Alive() && ply:GetNetworkedBool("thirdperson") then | ||||||
| 		angles = player:GetAimVector():Angle() | 		av = ply:GetAimVector() | ||||||
| 		 | 		 | ||||||
| 		local targetpos = Vector(0, 0, player:OBBMaxs().z) | 		if !av then return end | ||||||
| 		if player:KeyDown(IN_DUCK) then | 		 | ||||||
| 			if player:GetVelocity():Length() > 0 then | 		angles = av:Angle() | ||||||
|  | 
 | ||||||
|  | 		local targetpos = Vector(0, 0, ply:OBBMaxs().z) | ||||||
|  | 		if ply:KeyDown(IN_DUCK) then | ||||||
|  | 			if ply:GetVelocity():Length() > 0 then | ||||||
| 				targetpos.z = targetpos.z / 1.33 | 				targetpos.z = targetpos.z / 1.33 | ||||||
| 		 	else | 		 	else | ||||||
| 				targetpos.z = targetpos.z / 2 | 				targetpos.z = targetpos.z / 2 | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 
 | 
 | ||||||
| 		player:SetAngles(angles) | 		ply:SetAngles(angles) | ||||||
| 		 | 		 | ||||||
| 		local targetfov = fov | 		local targetfov = fov | ||||||
| 		if player:GetVelocity():DotProduct(player:GetForward()) > 10 then | 		if ply:GetVelocity():DotProduct(ply:GetForward()) > 10 then | ||||||
| 			if player:KeyDown(IN_SPEED) then | 			if ply:KeyDown(IN_SPEED) then | ||||||
| 				targetpos = targetpos + player:GetForward() * -10 | 				targetpos = targetpos + ply:GetForward() * -10 | ||||||
| 			else | 			else | ||||||
| 				targetpos = targetpos + player:GetForward() * -5 | 				targetpos = targetpos + ply:GetForward() * -5 | ||||||
| 			end | 			end | ||||||
| 		end  | 		end  | ||||||
| 		 | 		 | ||||||
| 		// smoothing - approaches a bit more slowly to the actual target position | 		// smoothing - approaches a bit more slowly to the actual target position | ||||||
| 		pos = targetpos |  | ||||||
| 		pos = Vector( | 		pos = Vector( | ||||||
| 			math.Approach(pos.x, targetpos.x, math.abs(targetpos.x - pos.x) * smoothscale), | 			math.Approach(pos.x, targetpos.x, math.abs(targetpos.x - pos.x) * smoothscale), | ||||||
| 			math.Approach(pos.y, targetpos.y, math.abs(targetpos.y - pos.y) * smoothscale), | 			math.Approach(pos.y, targetpos.y, math.abs(targetpos.y - pos.y) * smoothscale), | ||||||
|  | @ -63,16 +66,16 @@ hook.Add("CalcView", "Disguiser.ThirdPersonCalcView", function(player, pos, angl | ||||||
| 		 | 		 | ||||||
| 		// offset it by the stored amounts, but trace so it stays outside walls | 		// offset it by the stored amounts, but trace so it stays outside walls | ||||||
| 		// we don't smooth this so the camera feels like its tightly following the mouse | 		// we don't smooth this so the camera feels like its tightly following the mouse | ||||||
| 		local offset = Vector(50 + (player:OBBMaxs().z - player:OBBMins().z), 0, 10) | 		local offset = Vector(50 + (ply:OBBMaxs().z - ply:OBBMins().z), 0, 10) | ||||||
| 		local t = { | 		local t = { | ||||||
| 			start = player:GetPos() + pos, | 			start = ply:GetPos() + pos, | ||||||
| 			endpos = (player:GetPos() + pos) | 			endpos = (ply:GetPos() + pos) | ||||||
| 				+ (angles:Forward() * -offset.x) | 				+ (angles:Forward() * -offset.x) | ||||||
| 				+ (angles:Right() * offset.y) | 				+ (angles:Right() * offset.y) | ||||||
| 				+ (angles:Up() * offset.z), | 				+ (angles:Up() * offset.z), | ||||||
| 			filter = player | 			filter = ply | ||||||
| 		} | 		} | ||||||
| 		if player:GetVehicle():IsValid() then | 		if ply:GetVehicle():IsValid() then | ||||||
| 			pos = t.endpos | 			pos = t.endpos | ||||||
| 		else | 		else | ||||||
| 			local tr = util.TraceLine(t) | 			local tr = util.TraceLine(t) | ||||||
|  | @ -83,24 +86,22 @@ hook.Add("CalcView", "Disguiser.ThirdPersonCalcView", function(player, pos, angl | ||||||
| 		end | 		end | ||||||
| 
 | 
 | ||||||
| 		// Smoothing FOV change | 		// Smoothing FOV change | ||||||
| 		fov = targetfov | 		fov = targetfov -- comment or remove this to enable smoothing | ||||||
| 		fov = math.Approach(fov, targetfov, math.abs(targetfov - fov) * smoothscale) | 		fov = math.Approach(fov, targetfov, math.abs(targetfov - fov) * smoothscale) | ||||||
| 		 | 		 | ||||||
| 		return GAMEMODE:CalcView(player, pos, angles, fov) | 		return GAMEMODE:CalcView(ply, pos, angles, fov) | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
| 
 | 
 | ||||||
| hook.Add("HUDPaint", "Disguiser.ThirdPersonHUDPaint", function() | hook.Add("HUDPaint", "Disguiser.ThirdPersonHUDPaint", function() | ||||||
| 	local player = LocalPlayer() | 	local ply = LocalPlayer() | ||||||
| 	if !player:GetNetworkedBool("thirdperson") then |  | ||||||
| 		return |  | ||||||
| 	end |  | ||||||
| 	 | 	 | ||||||
|  | 	if IsValid(ply) && !!ply["GetAimVector"] && ply:Alive() && ply:GetNetworkedBool("thirdperson") then | ||||||
| 		// trace from muzzle to hit pos | 		// trace from muzzle to hit pos | ||||||
| 		local t = {} | 		local t = {} | ||||||
| 	t.start = player:GetShootPos() | 		t.start = ply:GetShootPos() | ||||||
| 	t.endpos = t.start + player:GetAimVector() * 9000 | 		t.endpos = t.start + ply:GetAimVector() * 9000 | ||||||
| 	t.filter = player | 		t.filter = ply | ||||||
| 		local tr = util.TraceLine(t) | 		local tr = util.TraceLine(t) | ||||||
| 		local pos = tr.HitPos:ToScreen() | 		local pos = tr.HitPos:ToScreen() | ||||||
| 		local fraction = math.min((tr.HitPos - t.start):Length(), 1024) / 1024 | 		local fraction = math.min((tr.HitPos - t.start):Length(), 1024) / 1024 | ||||||
|  | @ -111,9 +112,9 @@ hook.Add("HUDPaint", "Disguiser.ThirdPersonHUDPaint", function() | ||||||
| 
 | 
 | ||||||
| 		// trace from camera to hit pos, if blocked, red crosshair | 		// trace from camera to hit pos, if blocked, red crosshair | ||||||
| 		local tr = util.TraceLine({ | 		local tr = util.TraceLine({ | ||||||
| 		start = player:GetPos(), | 			start = ply:GetPos(), | ||||||
| 			endpos = tr.HitPos + tr.HitNormal * 5, | 			endpos = tr.HitPos + tr.HitNormal * 5, | ||||||
| 		filter = player, | 			filter = ply, | ||||||
| 			mask = MASK_SHOT | 			mask = MASK_SHOT | ||||||
| 		}) | 		}) | ||||||
| 		surface.SetDrawColor(255, 255, 255, 255) | 		surface.SetDrawColor(255, 255, 255, 255) | ||||||
|  | @ -126,10 +127,11 @@ hook.Add("HUDPaint", "Disguiser.ThirdPersonHUDPaint", function() | ||||||
| 		surface.DrawLine(pos.x, pos.y + offset, pos.x, pos.y + offset2) | 		surface.DrawLine(pos.x, pos.y + offset, pos.x, pos.y + offset2) | ||||||
| 		surface.DrawLine(pos.x - 1, pos.y, pos.x + 1, pos.y) | 		surface.DrawLine(pos.x - 1, pos.y, pos.x + 1, pos.y) | ||||||
| 		surface.DrawLine(pos.x, pos.y - 1, pos.x, pos.y + 1) | 		surface.DrawLine(pos.x, pos.y - 1, pos.x, pos.y + 1) | ||||||
|  | 	end | ||||||
| end) | end) | ||||||
| 
 | 
 | ||||||
| hook.Add("HUDShouldDraw", "Disguiser.ThirdPersonHUDShouldDraw", function(name) | hook.Add("HUDShouldDraw", "Disguiser.ThirdPersonHUDShouldDraw", function(name) | ||||||
| 	if name == "CHudCrosshair" and LocalPlayer():GetNetworkedInt("thirdperson") == 1 then | 	if name == "CHudCrosshair" and IsValid(LocalPlayer()) and LocalPlayer():Alive() and LocalPlayer():GetNetworkedBool("thirdperson") then | ||||||
| 		return false | 		return false | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
|  | @ -5,9 +5,8 @@ | ||||||
|  *   cl_fxfake.lua |  *   cl_fxfake.lua | ||||||
|  * |  * | ||||||
|  * Purpose: |  * Purpose: | ||||||
|  *   Fake shoot effect on client-side via a trigger from server-side, as |  *   Fake client-side effects via a user message trigger from server-side, as for some | ||||||
|  *   for some reason on multiplayer servers the effect is not rendered on |  *   reason these effects are not rendered on client-side automatically. | ||||||
|  *   client-side automatically. |  | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2013 Carl Kittelberger (Icedream) |  * Copyright (C) 2013 Carl Kittelberger (Icedream) | ||||||
|  * |  * | ||||||
|  | @ -32,10 +31,11 @@ usermessage.Hook("disguiserShootFX", function(um) | ||||||
| 	local physbone = um:ReadLong() | 	local physbone = um:ReadLong() | ||||||
| 	local bFirstTimePredicted = um:ReadBool() | 	local bFirstTimePredicted = um:ReadBool() | ||||||
| 	 | 	 | ||||||
| 	// Can we trigger shoot effect yet? | 	-- Can we trigger shoot effect yet? | ||||||
| 	if !LocalPlayer():GetActiveWeapon().DoShootEffect then return false end | 	swep = LocalPlayer():GetActiveWeapon() | ||||||
|  | 	if !swep.DoShootEffect then return false end | ||||||
| 	 | 	 | ||||||
| 	// Render shoot effect | 	-- Render shoot effect | ||||||
| 	LocalPlayer():GetActiveWeapon("disguiser"):DoShootEffect( | 	swep:DoShootEffect( | ||||||
| 		hitpos, hitnormal, entity, physbone, bFirstTimePredicted) | 		hitpos, hitnormal, entity, physbone, bFirstTimePredicted) | ||||||
| end) | end) | ||||||
|  | @ -105,7 +105,9 @@ function SWEP:Disguise(entity) | ||||||
| 	local owner = self.Owner | 	local owner = self.Owner | ||||||
| 	 | 	 | ||||||
| 	// Make sure we aren't already that model | 	// Make sure we aren't already that model | ||||||
| 	if (owner:GetModel() == entity:GetModel() && owner:GetSkin() == entity:GetSkin()) then return true end | 	if (owner:GetModel() == entity:GetModel() | ||||||
|  | 		&& owner:GetSkin() == entity:GetSkin() | ||||||
|  | 		&& owner:GetColor() == entity:GetColor()) then return true end | ||||||
| 	 | 	 | ||||||
| 	// Make sure the new model is actually marked as a prop | 	// Make sure the new model is actually marked as a prop | ||||||
| 	if ( | 	if ( | ||||||
|  | @ -125,7 +127,6 @@ function SWEP:Disguise(entity) | ||||||
| 		self.UndisguiseAsColor = owner:GetColor() | 		self.UndisguiseAsColor = owner:GetColor() | ||||||
| 		self.UndisguiseAsBloodColor = owner:GetBloodColor() | 		self.UndisguiseAsBloodColor = owner:GetBloodColor() | ||||||
| 		self.UndisguiseAsSolid = owner:GetSolid() | 		self.UndisguiseAsSolid = owner:GetSolid() | ||||||
| 		self.UndisguiseAsFullRotation = owner:GetAllowFullRotation() |  | ||||||
| 	end | 	end | ||||||
| 	 | 	 | ||||||
| 	// Disguise as given model | 	// Disguise as given model | ||||||
|  | @ -148,11 +149,7 @@ function SWEP:Disguise(entity) | ||||||
| 	// Apply new hull | 	// Apply new hull | ||||||
| 	local obbmaxs = entity:OBBMaxs() | 	local obbmaxs = entity:OBBMaxs() | ||||||
| 	local obbmins = entity:OBBMins() | 	local obbmins = entity:OBBMins() | ||||||
| 	/* | 	 | ||||||
| 	local obbmargin = Vector(2, 2, 0) |  | ||||||
| 	obbmaxs = obbmaxs + obbmargin |  | ||||||
| 	obbmins = obbmins - obbmargin |  | ||||||
| 	*/ |  | ||||||
| 	// Look for correction values | 	// Look for correction values | ||||||
| 	local pcfg = self:GetPropConfig(entity:GetModel()) | 	local pcfg = self:GetPropConfig(entity:GetModel()) | ||||||
| 	if !!pcfg["OBBMaxsCorrection"] then | 	if !!pcfg["OBBMaxsCorrection"] then | ||||||
|  | @ -212,7 +209,6 @@ function SWEP:Undisguise() | ||||||
| 	end | 	end | ||||||
| 	owner:SetColor(self.UndisguiseAsColor) | 	owner:SetColor(self.UndisguiseAsColor) | ||||||
| 	owner:SetSolid(self.UndisguiseAsSolid) | 	owner:SetSolid(self.UndisguiseAsSolid) | ||||||
| 	owner:SetAllowFullRotation(self.UndisguiseAsFullRotation) // up/down rotation |  | ||||||
| 	owner:SetBloodColor(self.UndisguiseAsBloodColor) | 	owner:SetBloodColor(self.UndisguiseAsBloodColor) | ||||||
| 	 | 	 | ||||||
| 	// Revert to old physics | 	// Revert to old physics | ||||||
|  | @ -227,7 +223,6 @@ function SWEP:Undisguise() | ||||||
| 	umsg.End() | 	umsg.End() | ||||||
| 	 | 	 | ||||||
| 	// Pop! | 	// Pop! | ||||||
| 	UndisguiseSilent() |  | ||||||
| 	owner:EmitSound("Disguiser.Undisguise") | 	owner:EmitSound("Disguiser.Undisguise") | ||||||
| 	 | 	 | ||||||
| 	// We're no longer disguised | 	// We're no longer disguised | ||||||
|  | @ -321,6 +316,7 @@ function SWEP:EnableThirdPerson(player) | ||||||
| 	entity:SetModel(player:GetModel()) | 	entity:SetModel(player:GetModel()) | ||||||
| 	entity:Spawn() | 	entity:Spawn() | ||||||
| 	entity:SetAngles(player:GetAngles()) | 	entity:SetAngles(player:GetAngles()) | ||||||
|  | 	entity:SetVelocity(player:GetVelocity()) | ||||||
| 	entity:SetMoveType(MOVETYPE_NONE) | 	entity:SetMoveType(MOVETYPE_NONE) | ||||||
| 	entity:SetParent(player) | 	entity:SetParent(player) | ||||||
| 	entity:SetOwner(player) | 	entity:SetOwner(player) | ||||||
|  | @ -333,26 +329,35 @@ function SWEP:EnableThirdPerson(player) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| hook.Add("PlayerDeath", "Disguiser.ThirdPersonDeath", function(victim, inflictor, killer) | hook.Add("PlayerDeath", "Disguiser.ThirdPersonDeath", function(victim, inflictor, killer) | ||||||
| 
 |  | ||||||
| 	victim:SetNetworkedBool("thirdperson", false) |  | ||||||
| 	victim:SetNetworkedBool("isDisguised", false) |  | ||||||
| 	local ventity = victim:GetViewEntity() |  | ||||||
| 	 |  | ||||||
| 	// Escape third-person mode | 	// Escape third-person mode | ||||||
|  | 	if victim:GetNWBool("thirdperson") then | ||||||
|  | 		victim:SetNetworkedBool("thirdperson", false) | ||||||
|  | 		 | ||||||
|  | 		local ventity = victim:GetViewEntity() | ||||||
| 		if (IsValid(ventity)) then | 		if (IsValid(ventity)) then | ||||||
| 		ventity:Remove() |  | ||||||
| 			victim:SetViewEntity(victim) | 			victim:SetViewEntity(victim) | ||||||
|  | 			ventity:Remove() | ||||||
|  | 		end | ||||||
| 	end | 	end | ||||||
| 	 | 	 | ||||||
| 	if (!!victim.Disguised) then | 	// Undisguise basically but with a few tweaks to avoid some bugs | ||||||
|  | 	if victim:GetNWBool("isDisguised") then | ||||||
|  | 		victim:SetNetworkedBool("isDisguised", false) | ||||||
|  | 		 | ||||||
| 		// fake entity for spectacular death! | 		// fake entity for spectacular death! | ||||||
| 		local dentity = ents.Create("prop_physics") | 		local dentity = ents.Create("prop_physics") | ||||||
| 		dentity:SetModel(victim:GetModel()) | 		dentity:SetModel(victim:GetModel()) | ||||||
|  | 		if !!victim:GetSkin() then | ||||||
|  | 			dentity:SetSkin(victim:GetSkin()) | ||||||
|  | 		end | ||||||
|  | 		dentity:SetColor(victim:GetColor()) | ||||||
| 		dentity:SetAngles(victim:GetAngles()) | 		dentity:SetAngles(victim:GetAngles()) | ||||||
| 		dentity:SetPos(victim:GetPos()) | 		dentity:SetPos(victim:GetPos()) | ||||||
| 		dentity:SetVelocity(victim:GetVelocity()) | 		dentity:SetVelocity(victim:GetVelocity()) | ||||||
| 		local physics = victim:GetPhysicsObject() | 		local physics = victim:GetPhysicsObject() | ||||||
| 		dentity:SetBloodColor(BLOOD_COLOR_RED) -- this thing was alive, ya know? :( | 		if !!victim:GetBloodColor() then | ||||||
|  | 			dentity:SetBloodColor(victim:GetBloodColor()) -- this thing was alive, ya know? :( | ||||||
|  | 		end | ||||||
| 		dentity:Spawn() | 		dentity:Spawn() | ||||||
| 		local dphysics = dentity:GetPhysicsObject() | 		local dphysics = dentity:GetPhysicsObject() | ||||||
| 		dphysics:SetAngles(physics:GetAngles()) | 		dphysics:SetAngles(physics:GetAngles()) | ||||||
|  | @ -360,13 +365,14 @@ hook.Add("PlayerDeath", "Disguiser.ThirdPersonDeath", function(victim, inflictor | ||||||
| 		dphysics:SetDamping(physics:GetDamping()) | 		dphysics:SetDamping(physics:GetDamping()) | ||||||
| 		dphysics:SetInertia(physics:GetInertia()) | 		dphysics:SetInertia(physics:GetInertia()) | ||||||
| 		dentity:Fire("break", "", 0) | 		dentity:Fire("break", "", 0) | ||||||
| 		dentity:Fire("kill", "", 2) | 		dentity:Fire("kill", "", 1) | ||||||
| 		dentity:Fire("enablemotion","",0) | 		dentity:Fire("enablemotion","",0) | ||||||
| 		 | 		 | ||||||
| 		// Manually draw additional blood (for some reason setting the blood color has no effect) | 		// Let the entity bleed wahahaha. I'm mad, ain't I? | ||||||
| 		local traceworld = {} | 		local traceworld = {} | ||||||
| 		traceworld.start = victim:GetPos() + Vector(0, 0, 20) | 		traceworld.start = victim:GetPos() + Vector(0, 0, 20) | ||||||
| 		traceworld.endpos = traceworld.start + (Vector(0,0,-1) * 8000) // aim max. 8000 units down | 		traceworld.endpos = traceworld.start + (Vector(0,0,-1) * 8000) // aim max. 8000 units down | ||||||
|  | 		traceworld.filter = victim | ||||||
| 		local trw = util.TraceLine(traceworld) // Send the trace and get the results. | 		local trw = util.TraceLine(traceworld) // Send the trace and get the results. | ||||||
| 		local edata = EffectData() | 		local edata = EffectData() | ||||||
| 		edata:SetStart(victim:GetPos() - physics:GetVelocity()) | 		edata:SetStart(victim:GetPos() - physics:GetVelocity()) | ||||||
|  | @ -374,7 +380,12 @@ hook.Add("PlayerDeath", "Disguiser.ThirdPersonDeath", function(victim, inflictor | ||||||
| 		edata:SetNormal(trw.Normal) | 		edata:SetNormal(trw.Normal) | ||||||
| 		edata:SetEntity(dentity) | 		edata:SetEntity(dentity) | ||||||
| 		util.Effect("BloodImpact", edata) | 		util.Effect("BloodImpact", edata) | ||||||
| 		util.Decal("Splash.Large", trw.HitPos + trw.HitNormal, trw.HitPos - trw.HitNormal) | 		 | ||||||
|  | 		// Reset the victim's bounding box to solve the issue with getting stuck at spawn | ||||||
|  | 		victim:ResetHull() | ||||||
|  | 		umsg.Start("resetHull", victim) | ||||||
|  | 		umsg.Entity(victim) | ||||||
|  | 		umsg.End() | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | Subproject commit 486129fa1ef1539071d14a366d686f3892c3d43f | ||||||
		Loading…
	
		Reference in New Issue