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
|