aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/inventory/common/weapons.lua
blob: 9067981d80905a984a7dd0a8ef12e27124ecf25f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
---Common functionality used in a lot of weapons.
-- Bits an peices that most weapons need
--@shared weapons.lua
--@alias com

local com = {}

--- Finds the direction a player is moveing.
-- @param player The player to find the move direction of
-- @return The string "forward", "backward", "right", or "left"
function com.playermovedir(player)
	local vel = player:GetVelocity():GetNormalized()
	vel.z = 0
	local swings = {
		{player:GetForward(),"forward"},
		{-player:GetForward(),"backward"},
		{player:GetRight(),"right"},
		{-player:GetRight(),"left"}
	}
	table.sort(swings,function(a,b)
		return vel:Dot(a[1]) > vel:Dot(b[1])
	end)
	return swings[1][2]
end

--- The arc swing of a weapon.
-- Finds anything that a weapon should hit in it's swing, and calls a function on it.
-- @param player The player that's swinging the weapon
-- @param times A table of times that the trace calculations should be done at, this table needs to be the same length as the positions table
-- @param positions The position offsets from the player that swung that should be the start/end points of the arc
-- @param onhit A function to call on any entities that were hit in the swing of the weapon.
function com.swingarc(player,times,positions,onhit)
	local positionpoints = {}
	--table.insert(positionset,positionpoints)
	for k,v in ipairs(times) do
		timer.Simple(v,function()
			ART.TraceWeapon = true
			ART.TraceStart = CurTime()
			local add = Vector(0,0,64)
			if player:Crouching() then
				add = Vector(0,0,32)
			end
			print("positions[k]",positions[k],"playerpos",player:GetPos(),"add",add)
			local weaponpos = positions[k] + player:GetPos() + add
			table.insert(positionpoints,weaponpos)
			if #positionpoints > 1 then
				--print("Trace from ", positionpoints[#positionpoints-1], " to ", positionpoints[#positionpoints])
				local tr = util.TraceLine({
					start = positionpoints[#positionpoints-1],
					endpos = positionpoints[#positionpoints],
				})
				onhit(tr)
			end
		end)
	end
	timer.Simple(times[#times],function()
		net.Start("setwepswing")
		net.WriteTable(positionpoints)
		net.Broadcast()
		--print("Inserted swing, drawn positions are now:")
		--PrintTable(positionset)
		ART.TraceWeapon = false
	end)
end

---Creates a new attack table.
-- Creates a table of ["forward|backward|left|right"] = function()
-- This is done before hand so that table is not re-generated on the fly each time a player attacks
--@tparam attacktbl tbl_attackdata The attack data to use
--@tparam entity attacker The entity attacking
function com.createattackstable(tbl_attackdata,attacker)
	local movementtbl = {}
	for k,v in pairs(tbl_attackdata) do
		movementtbl[k] = function()
			attacker:SetLuaAnimation(v.anim)
			timer.Simple(v.animtime,function()
				attacker:StopLuaAnimation(v.anim)
			end)
			local times, pos = {},{}
			for i,j in pairs(v.data) do
				times[i] = 1 + j[1]
				pos[i] = Vector(j[2])
				pos[i]:Rotate(attacker:GetAimVector():Angle())
			end
			if pos[1] == nil then return end
			com.swingarc(attacker,times,pos,function(tr)
				if not tr.Hit then return end
				if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == k then
					eff()
				elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= attacker then
					tr.Entity:TakeDamage(v.dammage,attacker,attacker:GetActiveWeapon())
				end
			end)
		end
	end

	--Empty functions for attacks not defined
	for k,v in pairs({"left","right","forward","backward"}) do
		if movementtbl[k] == nil then
			movementtbl[k] = function() end
		end
	end

	return movementtbl
end

if SERVER then
	util.AddNetworkString("setwepswing")
end
local positionset = {}

net.Receive("setwepswing",function()
	positionset = net.ReadTable()
	print("Got message to read positionset, is now")
	PrintTable(positionset)
end)

hook.Add( "HUDPaint", "weaponswings", function()
	cam.Start3D() -- Start the 3D function so we can draw onto the screen.
		local v = positionset
		for i = 1,#v-1 do
			render.DrawLine( v[i], v[i + 1], Color(255,0,0,255), false )
			render.DrawLine( v[i], v[i] + Vector(0,0,20),Color(0,255,0,255),false)
		end
		--render.SetMaterial( material ) -- Tell render what material we want, in this case the flash from the gravgun
		--render.DrawSprite( pos, 16, 16, white ) -- Draw the sprite in the middle of the map, at 16x16 in it's original colour with full alpha.
	cam.End3D()
end )

return com