aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS3
-rw-r--r--content/data/artery/maps/rp_subterranean/chests.txt0
-rw-r--r--content/data/artery/maps/rp_subterranean/npcs.txt1
-rw-r--r--content/materials/art_constable.pngbin0 -> 12765 bytes
-rw-r--r--content/materials/art_medic.pngbin0 -> 3101 bytes
-rw-r--r--entities/entities/npc_huntable/init.lua1
-rw-r--r--gamemode/autolua.lua37
-rw-r--r--gamemode/client/cl_legs.lua315
-rw-r--r--gamemode/client/cl_npcmap.lua24
-rw-r--r--gamemode/core/clienteffects/cl_effects.lua12
-rw-r--r--gamemode/core/clienteffects/sh_effects.lua10
-rw-r--r--gamemode/core/clienteffects/sv_effects.lua11
-rw-r--r--gamemode/core/npcmap/cl_npcmap.lua162
-rw-r--r--gamemode/core/npcmap/sv_npcmap.lua22
-rw-r--r--gamemode/shared.lua9
-rw-r--r--gamemode/shared/inventory.lua28
-rw-r--r--gamemode/shared/itemsystem/weapons/rustyaxe.lua209
-rw-r--r--gamemode/shared/itemsystem/weapons/scraphammer.lua134
-rw-r--r--gamemode/shared/itemsystem/weapons/seratedknife.lua46
-rw-r--r--gamemode/shared/itemsystem/weapons_common.lua19
-rw-r--r--gamemode/shared/loadnpcs.lua5
-rw-r--r--gamemode/shared/npcsystem/blockingdummy.lua105
-rw-r--r--gamemode/shared/npcsystem/dummy.lua95
-rw-r--r--gamemode/shared/sh_npcmap.lua27
-rw-r--r--gamemode/shared/sh_pac.lua29
-rw-r--r--gamemode/shared/shop.lua52
-rw-r--r--gamemode/tools/markarea/sh_markarea.lua4
-rw-r--r--gamemode/utility/mapfuncs.lua25
28 files changed, 1158 insertions, 227 deletions
diff --git a/AUTHORS b/AUTHORS
index 22f7876..ae48e0a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
Alexander "Apickx" Pickering (alexandermpickering@gmail.com) - Most of artery
-William "JetBoom" Moodhe (williammoodhe@gmail.com) - Lua Animation API
+William "JetBoom" Moodhe (williammoodhe@gmail.com) - AnimBoneLib (Lua Animation API)
+CapsAdmin - Pac3
diff --git a/content/data/artery/maps/rp_subterranean/chests.txt b/content/data/artery/maps/rp_subterranean/chests.txt
deleted file mode 100644
index e69de29..0000000
--- a/content/data/artery/maps/rp_subterranean/chests.txt
+++ /dev/null
diff --git a/content/data/artery/maps/rp_subterranean/npcs.txt b/content/data/artery/maps/rp_subterranean/npcs.txt
deleted file mode 100644
index 82b595a..0000000
--- a/content/data/artery/maps/rp_subterranean/npcs.txt
+++ /dev/null
@@ -1 +0,0 @@
-{"procedures":{"SetModel":["models/player/Group02/Male_01.mdl"]}}
diff --git a/content/materials/art_constable.png b/content/materials/art_constable.png
new file mode 100644
index 0000000..32c4338
--- /dev/null
+++ b/content/materials/art_constable.png
Binary files differ
diff --git a/content/materials/art_medic.png b/content/materials/art_medic.png
new file mode 100644
index 0000000..a779b5b
--- /dev/null
+++ b/content/materials/art_medic.png
Binary files differ
diff --git a/entities/entities/npc_huntable/init.lua b/entities/entities/npc_huntable/init.lua
index e5b52c8..6b4c000 100644
--- a/entities/entities/npc_huntable/init.lua
+++ b/entities/entities/npc_huntable/init.lua
@@ -39,6 +39,7 @@ function ENT:Initialize()
end
function ENT:OnInjured(dmg)
+ print("Ent OnInjured fired!")
if self.OnDammage ~= nil then
self:OnDammage(dmg)
end
diff --git a/gamemode/autolua.lua b/gamemode/autolua.lua
index d550b83..44e146c 100644
--- a/gamemode/autolua.lua
+++ b/gamemode/autolua.lua
@@ -2,8 +2,12 @@
A few functions to make it easier to include files and folders
Thanks to TheMaw for this idea, this entire file is basically ripped form GearFox.
- You can AddLua(SV|SH|CS)Folder(foldername) to add that folder in the domain.
- Additionally, in the shared domain, if a folder has the folders sv_*.lua and cl_*.lua, and optionally sh_*.lua, these will be included in the server, client, and shared domain respectively.
+ module functions:
+ a.AddMixedFolder(foldername, recursive) :: nil
+ DarkRP style file include(cl_,sv_,sh_)
+ a.AddCSLuaFolder(foldername,recursive) :: nil
+ a.AddSHLuaFolder(foldername,recursive) :: nil
+ a.AddSVLuaFolder(foldername,recursive) :: nil
]]
-- @module autolua
local auto = {}
@@ -26,6 +30,23 @@ local function ExecuteOnFolder(dir, recursive, func)
end
end
+auto.AddMixedFolder = function(dir,recursive)
+ ExecuteOnFolder(dir,recursive,function(f)
+ print("Doing file"..f)
+ if f:find("/cl_%w+%.lua$") then
+ print("found cl")
+ if SERVER then AddCSLuaFile(f) else include(f) end
+ elseif f:find("/sv_%w+%.lua$") then
+ print("Foudn sv")
+ if SERVER then include(f) end
+ else
+ print("otherwise")
+ if SERVER then AddCSLuaFile(f) end
+ include(f)
+ end
+ end)
+end
+
--- Adds files client side.
-- Calls AddCSLuaFile on all files under a folder server side, and include() client side, if the recursive flag is checked, calls all files under all folders as well.
-- @string dir The directory relative to /gamemode/ to add client side
@@ -49,19 +70,13 @@ auto.AddLuaSVFolder = function(dir,recursive)
end
--- Adds files server side.
--- Calls include() and AddCSLuaFile() on all files under a folder server side, and include() client side, if the recursive flag is checked, calls all files under all folders as well. If the file starts with cl_ it will only be included on the client side, if the files starts with sv_ it will only be included on the server side.
+-- Calls include() and AddCSLuaFile() on all files under a folder server side, and include() client side, if the recursive flag is checked, calls all files under all folders as well.
-- @string dir The directory relative to /gamemode/ to add client side
-- @param recursive boolean value that when true includes all sub-folders recursively.
auto.AddLuaSHFolder = function(dir,recursive)
ExecuteOnFolder(dir,recursive,function(f)
- if f:find("cl_%a*.lua") then
- AddCSLuaFile(f)
- elseif f:find("sv_%a.lua") then
- if SERVER then include(f) end
- else
- if SERVER then AddCSLuaFile(f) end
- include(f)
- end
+ if SERVER then AddCSLuaFile(f) end
+ include(f)
end)
end
diff --git a/gamemode/client/cl_legs.lua b/gamemode/client/cl_legs.lua
new file mode 100644
index 0000000..1bfaa99
--- /dev/null
+++ b/gamemode/client/cl_legs.lua
@@ -0,0 +1,315 @@
+--[[
+
+ The purpose of this file is to render the client's legs
+ for realism purposes, this file wasn't coded by any of the
+ NightZ team it was however coded by Valkyrie:
+
+ http://facepunch.com/showthread.php?t=1227980&p=38680440&viewfull=1#post38680440
+
+--]]
+
+local Legs = {}
+Legs.LegEnt = nil
+
+function ShouldDrawLegs()
+ return IsValid( Legs.LegEnt ) and
+ ( LocalPlayer():Alive() or ( LocalPlayer().IsGhosted and LocalPlayer():IsGhosted() ) ) and
+ !Legs:CheckDrawVehicle() and
+ GetViewEntity() == LocalPlayer() and
+ !LocalPlayer():ShouldDrawLocalPlayer() and
+ !LocalPlayer():GetObserverTarget() and
+ !LocalPlayer().ShouldDisableLegs
+end
+
+function GetPlayerLegs( ply )
+ return ply and ply != LocalPlayer() and ply or ( ShouldDrawLegs() and Legs.LegEnt or LocalPlayer() )
+end
+
+Legs.FixedModelNames = {
+ ["models/humans/group01/female_06.mdl"] = "models/player/group01/female_06.mdl",
+ ["models/humans/group01/female_01.mdl"] = "models/player/group01/female_01.mdl",
+ ["models/alyx.mdl"] = "models/player/alyx.mdl",
+ ["models/humans/group01/female_07.mdl"] = "models/player/group01/female_07.mdl",
+ ["models/charple01.mdl"] = "models/player/charple01.mdl",
+ ["models/humans/group01/female_04.mdl"] = "models/player/group01/female_04.mdl",
+ ["models/humans/group03/female_06.mdl"] = "models/player/group03/female_06.mdl",
+ ["models/gasmask.mdl"] = "models/player/gasmask.mdl",
+ ["models/humans/group01/female_02.mdl"] = "models/player/group01/female_02.mdl",
+ ["models/gman_high.mdl"] = "models/player/gman_high.mdl",
+ ["models/humans/group03/male_07.mdl"] = "models/player/group03/male_07.mdl",
+ ["models/humans/group03/female_03.mdl"] = "models/player/group03/female_03.mdl",
+ ["models/police.mdl"] = "models/player/police.mdl",
+ ["models/breen.mdl"] = "models/player/breen.mdl",
+ ["models/humans/group01/male_01.mdl"] = "models/player/group01/male_01.mdl",
+ ["models/zombie_soldier.mdl"] = "models/player/zombie_soldier.mdl",
+ ["models/humans/group01/male_03.mdl"] = "models/player/group01/male_03.mdl",
+ ["models/humans/group03/female_04.mdl"] = "models/player/group03/female_04.mdl",
+ ["models/humans/group01/male_02.mdl"] = "models/player/group01/male_02.mdl",
+ ["models/kleiner.mdl"] = "models/player/kleiner.mdl",
+ ["models/humans/group03/female_01.mdl"] = "models/player/group03/female_01.mdl",
+ ["models/humans/group01/male_09.mdl"] = "models/player/group01/male_09.mdl",
+ ["models/humans/group03/male_04.mdl"] = "models/player/group03/male_04.mdl",
+ ["models/player/urban.mbl"] = "models/player/urban.mdl",
+ ["models/humans/group03/male_01.mdl"] = "models/player/group03/male_01.mdl",
+ ["models/mossman.mdl"] = "models/player/mossman.mdl",
+ ["models/humans/group01/male_06.mdl"] = "models/player/group01/male_06.mdl",
+ ["models/humans/group03/female_02.mdl"] = "models/player/group03/female_02.mdl",
+ ["models/humans/group01/male_07.mdl"] = "models/player/group01/male_07.mdl",
+ ["models/humans/group01/female_03.mdl"] = "models/player/group01/female_03.mdl",
+ ["models/humans/group01/male_08.mdl"] = "models/player/group01/male_08.mdl",
+ ["models/humans/group01/male_04.mdl"] = "models/player/group01/male_04.mdl",
+ ["models/humans/group03/female_07.mdl"] = "models/player/group03/female_07.mdl",
+ ["models/humans/group03/male_02.mdl"] = "models/player/group03/male_02.mdl",
+ ["models/humans/group03/male_06.mdl"] = "models/player/group03/male_06.mdl",
+ ["models/barney.mdl"] = "models/player/barney.mdl",
+ ["models/humans/group03/male_03.mdl"] = "models/player/group03/male_03.mdl",
+ ["models/humans/group03/male_05.mdl"] = "models/player/group03/male_05.mdl",
+ ["models/odessa.mdl"] = "models/player/odessa.mdl",
+ ["models/humans/group03/male_09.mdl"] = "models/player/group03/male_09.mdl",
+ ["models/humans/group01/male_05.mdl"] = "models/player/group01/male_05.mdl",
+ ["models/humans/group03/male_08.mdl"] = "models/player/group03/male_08.mdl",
+ ["models/monk.mdl"] = "models/player/monk.mdl",
+ ["models/eli.mdl"] = "models/player/eli.mdl",
+}
+
+function Legs:FixModelName( mdl )
+ mdl = mdl:lower()
+ return self.FixedModelNames[ mdl ] or mdl
+end
+
+function Legs:SetUp()
+ self.LegEnt = ClientsideModel( Legs:FixModelName( LocalPlayer():GetModel() ), RENDER_GROUP_OPAQUE_ENTITY )
+ self.LegEnt:SetNoDraw( true )
+ self.LegEnt:SetSkin( LocalPlayer():GetSkin() )
+ self.LegEnt:SetMaterial( LocalPlayer():GetMaterial() )
+ self.LegEnt.LastTick = 0
+end
+
+
+Legs.PlaybackRate = 1
+Legs.Sequence = nil
+Legs.Velocity = 0
+Legs.OldWeapon = nil
+Legs.HoldType = nil
+
+Legs.BoneHoldTypes = { ["none"] = {
+ "ValveBiped.Bip01_Head1",
+ "ValveBiped.Bip01_Neck1",
+ "ValveBiped.Bip01_Spine4",
+ "ValveBiped.Bip01_Spine2",
+ },
+ ["default"] = {
+ "ValveBiped.Bip01_Head1",
+ "ValveBiped.Bip01_Neck1",
+ "ValveBiped.Bip01_Spine4",
+ "ValveBiped.Bip01_Spine2",
+ "ValveBiped.Bip01_L_Hand",
+ "ValveBiped.Bip01_L_Forearm",
+ "ValveBiped.Bip01_L_Upperarm",
+ "ValveBiped.Bip01_L_Clavicle",
+ "ValveBiped.Bip01_R_Hand",
+ "ValveBiped.Bip01_R_Forearm",
+ "ValveBiped.Bip01_R_Upperarm",
+ "ValveBiped.Bip01_R_Clavicle",
+ "ValveBiped.Bip01_L_Finger4",
+ "ValveBiped.Bip01_L_Finger41",
+ "ValveBiped.Bip01_L_Finger42",
+ "ValveBiped.Bip01_L_Finger3",
+ "ValveBiped.Bip01_L_Finger31",
+ "ValveBiped.Bip01_L_Finger32",
+ "ValveBiped.Bip01_L_Finger2",
+ "ValveBiped.Bip01_L_Finger21",
+ "ValveBiped.Bip01_L_Finger22",
+ "ValveBiped.Bip01_L_Finger1",
+ "ValveBiped.Bip01_L_Finger11",
+ "ValveBiped.Bip01_L_Finger12",
+ "ValveBiped.Bip01_L_Finger0",
+ "ValveBiped.Bip01_L_Finger01",
+ "ValveBiped.Bip01_L_Finger02",
+ "ValveBiped.Bip01_R_Finger4",
+ "ValveBiped.Bip01_R_Finger41",
+ "ValveBiped.Bip01_R_Finger42",
+ "ValveBiped.Bip01_R_Finger3",
+ "ValveBiped.Bip01_R_Finger31",
+ "ValveBiped.Bip01_R_Finger32",
+ "ValveBiped.Bip01_R_Finger2",
+ "ValveBiped.Bip01_R_Finger21",
+ "ValveBiped.Bip01_R_Finger22",
+ "ValveBiped.Bip01_R_Finger1",
+ "ValveBiped.Bip01_R_Finger11",
+ "ValveBiped.Bip01_R_Finger12",
+ "ValveBiped.Bip01_R_Finger0",
+ "ValveBiped.Bip01_R_Finger01",
+ "ValveBiped.Bip01_R_Finger02"
+ },
+ ["vehicle"] = {
+ "ValveBiped.Bip01_Head1",
+ "ValveBiped.Bip01_Neck1",
+ "ValveBiped.Bip01_Spine4",
+ "ValveBiped.Bip01_Spine2",
+ }
+ }
+
+Legs.BonesToRemove = {}
+Legs.BoneMatrix = nil
+
+function Legs:WeaponChanged( weap )
+ if IsValid( self.LegEnt ) then
+ if IsValid( weap ) then
+ self.HoldType = weap:GetHoldType()
+ else
+ self.HoldType = "none"
+ end
+
+ for boneId = 0, self.LegEnt:GetBoneCount() do
+ self.LegEnt:ManipulateBoneScale(boneId, Vector(1,1,1))
+ self.LegEnt:ManipulateBonePosition(boneId, Vector(0,0,0))
+ end
+
+ Legs.BonesToRemove = {
+ "ValveBiped.Bip01_Head1"
+ }
+ if !LocalPlayer():InVehicle() then
+ Legs.BonesToRemove = Legs.BoneHoldTypes[ Legs.HoldType ] or Legs.BoneHoldTypes[ "default" ]
+ else
+ Legs.BonesToRemove = Legs.BoneHoldTypes[ "vehicle" ]
+ end
+ for _, v in pairs( Legs.BonesToRemove ) do
+ local boneId = self.LegEnt:LookupBone(v)
+ if boneId then
+ self.LegEnt:ManipulateBoneScale(boneId, vector_origin)
+ self.LegEnt:ManipulateBonePosition(boneId, Vector(-10,-10,0))
+ end
+ end
+ end
+end
+
+Legs.BreathScale = 0.5
+Legs.NextBreath = 0
+
+function Legs:Think( maxseqgroundspeed )
+ if IsValid( self.LegEnt ) then
+ if LocalPlayer():GetActiveWeapon() != self.OldWeapon then
+ self.OldWeapon = LocalPlayer():GetActiveWeapon()
+ self:WeaponChanged( self.OldWeapon )
+ end
+
+ if self.LegEnt:GetModel() != self:FixModelName( LocalPlayer():GetModel() ) then
+ self.LegEnt:SetModel( self:FixModelName( LocalPlayer():GetModel() ) )
+ end
+
+ self.LegEnt:SetMaterial( LocalPlayer():GetMaterial() )
+ self.LegEnt:SetSkin( LocalPlayer():GetSkin() )
+
+ self.Velocity = LocalPlayer():GetVelocity():Length2D()
+
+ self.PlaybackRate = 1
+
+ if self.Velocity > 0.5 then
+ if maxseqgroundspeed < 0.001 then
+ self.PlaybackRate = 0.01
+ else
+ self.PlaybackRate = self.Velocity / maxseqgroundspeed
+ self.PlaybackRate = math.Clamp( self.PlaybackRate, 0.01, 10 )
+ end
+ end
+
+ self.LegEnt:SetPlaybackRate( self.PlaybackRate )
+
+ self.Sequence = LocalPlayer():GetSequence()
+
+ if ( self.LegEnt.Anim != self.Sequence ) then
+ self.LegEnt.Anim = self.Sequence
+ self.LegEnt:ResetSequence( self.Sequence )
+ end
+
+ self.LegEnt:FrameAdvance( CurTime() - self.LegEnt.LastTick )
+ self.LegEnt.LastTick = CurTime()
+
+ Legs.BreathScale = sharpeye and sharpeye.GetStamina and math.Clamp( math.floor( sharpeye.GetStamina() * 5 * 10 ) / 10, 0.5, 5 ) or 0.5
+
+ if Legs.NextBreath <= CurTime() then
+ Legs.NextBreath = CurTime() + 1.95 / Legs.BreathScale
+ self.LegEnt:SetPoseParameter( "breathing", Legs.BreathScale )
+ end
+
+ self.LegEnt:SetPoseParameter( "move_x", ( LocalPlayer():GetPoseParameter( "move_x" ) * 2 ) - 1 )
+ self.LegEnt:SetPoseParameter( "move_y", ( LocalPlayer():GetPoseParameter( "move_y" ) * 2 ) - 1 )
+ self.LegEnt:SetPoseParameter( "move_yaw", ( LocalPlayer():GetPoseParameter( "move_yaw" ) * 360 ) - 180 )
+ self.LegEnt:SetPoseParameter( "body_yaw", ( LocalPlayer():GetPoseParameter( "body_yaw" ) * 180 ) - 90 )
+ self.LegEnt:SetPoseParameter( "spine_yaw",( LocalPlayer():GetPoseParameter( "spine_yaw" ) * 180 ) - 90 )
+
+ if ( LocalPlayer():InVehicle() ) then
+ self.LegEnt:SetColor( color_transparent )
+ self.LegEnt:SetPoseParameter( "vehicle_steer", ( LocalPlayer():GetVehicle():GetPoseParameter( "vehicle_steer" ) * 2 ) - 1 )
+ end
+ end
+end
+
+hook.Add( "UpdateAnimation", "Legs:UpdateAnimation", function( ply, velocity, maxseqgroundspeed )
+ if ply == LocalPlayer() then
+ if IsValid( Legs.LegEnt ) then
+ Legs:Think( maxseqgroundspeed )
+ else
+ Legs:SetUp()
+ end
+ end
+end )
+
+Legs.RenderAngle = nil
+Legs.BiaisAngle = nil
+Legs.RadAngle = nil
+Legs.RenderPos = nil
+Legs.RenderColor = {}
+Legs.ClipVector = vector_up * -1
+Legs.ForwardOffset = -24
+
+function Legs:CheckDrawVehicle()
+ return LocalPlayer():InVehicle()
+end
+
+hook.Add( "RenderScreenspaceEffects", "Legs:Render", function()
+ cam.Start3D( EyePos(), EyeAngles() )
+ if ShouldDrawLegs() then
+
+ Legs.RenderPos = LocalPlayer():GetPos()
+ if LocalPlayer():InVehicle() then
+ Legs.RenderAngle = LocalPlayer():GetVehicle():GetAngles()
+ Legs.RenderAngle:RotateAroundAxis( Legs.RenderAngle:Up(), 90 )
+ else
+ Legs.BiaisAngles = sharpeye_focus and sharpeye_focus.GetBiaisViewAngles and sharpeye_focus:GetBiaisViewAngles() or LocalPlayer():EyeAngles()
+ Legs.RenderAngle = Angle( 0, Legs.BiaisAngles.y, 0 )
+ Legs.RadAngle = math.rad( Legs.BiaisAngles.y )
+ Legs.ForwardOffset = -22
+ Legs.RenderPos.x = Legs.RenderPos.x + math.cos( Legs.RadAngle ) * Legs.ForwardOffset
+ Legs.RenderPos.y = Legs.RenderPos.y + math.sin( Legs.RadAngle ) * Legs.ForwardOffset
+
+ if LocalPlayer():GetGroundEntity() == NULL then
+ Legs.RenderPos.z = Legs.RenderPos.z + 8
+ if LocalPlayer():KeyDown( IN_DUCK ) then
+ Legs.RenderPos.z = Legs.RenderPos.z - 28
+ end
+ end
+ end
+
+ Legs.RenderColor = LocalPlayer():GetColor()
+
+ local bEnabled = render.EnableClipping( true )
+ render.PushCustomClipPlane( Legs.ClipVector, Legs.ClipVector:Dot( EyePos() ) )
+ render.SetColorModulation( Legs.RenderColor.r / 255, Legs.RenderColor.g / 255, Legs.RenderColor.b / 255 )
+ render.SetBlend( Legs.RenderColor.a / 255 )
+ hook.Call( "PreLegsDraw", GAMEMODE, Legs.LegEnt )
+ Legs.LegEnt:SetRenderOrigin( Legs.RenderPos )
+ Legs.LegEnt:SetRenderAngles( Legs.RenderAngle )
+ Legs.LegEnt:SetupBones()
+ Legs.LegEnt:DrawModel()
+ Legs.LegEnt:SetRenderOrigin()
+ Legs.LegEnt:SetRenderAngles()
+ hook.Call( "PostLegsDraw", GAMEMODE, Legs.LegEnt )
+ render.SetBlend( 1 )
+ render.SetColorModulation( 1, 1, 1 )
+ render.PopCustomClipPlane()
+ render.EnableClipping( bEnabled )
+ end
+ cam.End3D()
+end ) \ No newline at end of file
diff --git a/gamemode/client/cl_npcmap.lua b/gamemode/client/cl_npcmap.lua
deleted file mode 100644
index 784ca45..0000000
--- a/gamemode/client/cl_npcmap.lua
+++ /dev/null
@@ -1,24 +0,0 @@
-
-local drawmap = false
-hook.Add( "ScoreboardShow", "ShowNPCMap", function()
- print("Showing npc map")
- drawmap = true
- return true
-end )
-hook.Add( "ScoreboardHide", "ShowNPCMap", function()
- print("Hiding npc map")
- drawmap = false
-end )
-local white = Color( 255, 255, 255, 255 )
-
-hook.Add( "HUDPaint", "paintsprites", function()
- if drawmap then
- LocalPlayer().MapIcons = LocalPlayer().MapIcons or {}
- cam.Start3D()
- for k,v in pairs(LocalPlayer().MapIcons) do
- render.SetMaterial( v.material )
- render.DrawSprite( v.pos, 64, 64, white )
- end
- cam.End3D()
- end
-end )
diff --git a/gamemode/core/clienteffects/cl_effects.lua b/gamemode/core/clienteffects/cl_effects.lua
new file mode 100644
index 0000000..d51cf7d
--- /dev/null
+++ b/gamemode/core/clienteffects/cl_effects.lua
@@ -0,0 +1,12 @@
+
+local effects = {}
+effects["weapon_blocked"] = function()
+ util.ScreenShake( LocalPlayer():GetPos(), 3, 3, 0.25, 100 )
+end
+
+net.Receive("art_clienteffect",function()
+ local effectid = net.ReadUInt(32)
+ local effectname = ART.screen_effect_ids[effectid]
+ print("Got effect name",effectname)
+ effects[effectname]()
+end)
diff --git a/gamemode/core/clienteffects/sh_effects.lua b/gamemode/core/clienteffects/sh_effects.lua
new file mode 100644
index 0000000..70f3a79
--- /dev/null
+++ b/gamemode/core/clienteffects/sh_effects.lua
@@ -0,0 +1,10 @@
+ART = ART or {}
+
+ART.screen_effect_ids = {
+ "weapon_blocked"
+}
+
+ART.screen_effect_names = {}
+for k,v in pairs(ART.screen_effect_ids) do
+ ART.screen_effect_names[v] = k
+end
diff --git a/gamemode/core/clienteffects/sv_effects.lua b/gamemode/core/clienteffects/sv_effects.lua
new file mode 100644
index 0000000..2a8e083
--- /dev/null
+++ b/gamemode/core/clienteffects/sv_effects.lua
@@ -0,0 +1,11 @@
+
+ART = ART or {}
+
+util.AddNetworkString("art_clienteffect")
+
+ART.ApplyEffect = function(who,effectname)
+ assert(ART.screen_effect_names[effectname] ~= nil,"Attempted to call a nil effect name:" .. effectname .. ". Valid effect names:" .. table.concat(ART.screen_effect_ids,","))
+ net.Start("art_clienteffect")
+ net.WriteUInt(ART.screen_effect_names[effectname],32)
+ net.Send(who)
+end
diff --git a/gamemode/core/npcmap/cl_npcmap.lua b/gamemode/core/npcmap/cl_npcmap.lua
new file mode 100644
index 0000000..5a9de7e
--- /dev/null
+++ b/gamemode/core/npcmap/cl_npcmap.lua
@@ -0,0 +1,162 @@
+
+--local tblf = include("/../gamemodes/artery/gamemode/utility/mapfuncs.lua")
+print("Hello from cl_ncpmap in core")
+local drawmap = false
+hook.Add( "ScoreboardShow", "ShowNPCMap", function()
+ print("Showing npc map")
+ drawmap = true
+ return true
+end )
+hook.Add( "ScoreboardHide", "ShowNPCMap", function()
+ print("Hiding npc map")
+ drawmap = false
+end )
+local white = Color( 255, 255, 255, 255 )
+
+local mapicons = --[[mapicons or]] {
+ ["global"] = {
+ ["isleaf"] = false,
+ ["border"] = { {-10000,-10000},
+ {-10000,10000},
+ {10000,10000},
+ {10000,-10000}
+ },
+ }
+}
+
+hook.Add( "HUDPaint", "paintsprites", function()
+ local function drawsubarea(node)
+ print("drawing")
+ PrintTable(node)
+ if node.isleaf then
+ render.SetMaterial( node.material )
+ render.DrawSprite( node.pos, 64, 64, white )
+ print("Actually drawing")
+ PrintTable(node)
+ else
+ if not node.icons then
+ print("found area without any icons!")
+ for k,v in pairs(node) do print(k,":",v) end
+ end
+ for k,v in pairs(node.icons or {}) do
+ drawsubarea(v)
+ end
+ end
+ end
+ if drawmap then
+ print("starting this draw")
+ cam.Start3D()
+ drawsubarea(mapicons["global"])
+ cam.End3D()
+ print("done with this draw")
+ end
+end )
+
+--When the player loads in, load the npcmap for this map
+hook.Add("Initialize","loadmapicons",function()
+ LocalPlayer().MapIcons = LocalPlayer().MapIcons or {}
+ local mapname = game.GetMap()
+ if not file.Exists("artery/client/"..mapname,"DATA") then
+ file.CreateDir("artery/client/"..mapname)
+ end
+
+ local mapiconstxt = file.Read("artery/client/"..mapname.."/known.txt")
+ for k,v in pairs(string.Explode("\r?\n",mapiconstxt,true)) do
+ local isleaf = tobool(v[1])
+ local ttbl = string.Explode(",",v)
+ if isleaf then
+ local subarea = ttbl[2]
+ local material = ttbl[3]
+ local pos = Vector(ttbl[4],ttbl[5],ttbl[6])
+ else
+ local name = v[2]
+ local boundry = {}
+ for i = 3, #ttbl, 3 do
+ boundry[#boundry+1] = ttbl[i],ttbl[i + 1],ttbl[i + 2]
+ end
+ end
+ end
+end)
+
+--When the player disconnects (or changes levels) save the npcmap
+
+--Add an icon to the map
+local function addmapicon(material, subarea, position)
+ print("adding map icon, material:",material,"subarea:",subarea,"bordertbl:",bordertbl)
+ print("mat",material,"subarea",subarea,"position",position)
+ local parts = string.Explode(":",subarea)
+ print("parts:",parts)
+ PrintTable(parts)
+ local cursor = mapicons
+ for k,v in pairs(parts) do
+ print("Traverseing down tree:",k,v)
+ print("cursor was")
+ PrintTable(cursor)
+ if cursor[v] == nil then cursor[v] = {} end
+ cursor = cursor[v]
+ print("cursor is")
+ PrintTable(cursor)
+ end
+ if cursor.isleaf and v.pos == position then return end
+ cursor.icons = cursor.icons or {}
+ for k,v in pairs(cursor.icons) do
+ if v.pos == position then return end --This position already has an icon!
+ end
+ table.insert(cursor.icons,{
+ ["isleaf"] = true,
+ ["material"] = Material(material),
+ ["pos"] = position,
+ })
+ assert(type(cursor) == "table","Attempted to add subarea that dosen't exist:" .. subarea)
+end
+
+local function addmaparea(material, subarea, bordertbl)
+ print("adding map area, material:",material,"subarea:",subarea,"bordertbl:",bordertbl)
+ local parts = string.Explode(":",subarea)
+ print("parts:",parts)
+ PrintTable(parts)
+ local cursor = mapicons
+ if #parts > 1 then
+ for k,v in pairs(parts) do
+ print("Traverseing down tree:",k,v)
+ cursor = cursor[v]
+ end
+ end
+
+ print("Cursor is",cursor)
+ if cursor ~= nil then
+ cursor[subarea] = {
+ ["isleaf"] = false,
+ ["material"] = "",
+ ["border"] = bordertbl,
+ ["subparts"] = {}
+ }
+ else
+ print("Error, cursor was nil!")
+ end
+end
+--[[
+addmaparea("","global",{
+ {-10000,-10000},
+ {-10000,10000},
+ {10000,10000},
+ {10000,-10000}
+})
+]]
+
+net.Receive("addmapicon",function()
+ print("got recieve for map icon")
+ local matstr = net.ReadString()
+ local subarea = net.ReadString()
+ local matpos = net.ReadVector()
+ addmapicon(matstr,subarea,matpos)
+ print("MapIcons is now")
+ PrintTable(mapicons)
+end)
+
+net.Receive("addmaparea",function()
+ print("got receive for map area")
+ local matstr = net.ReadString()
+ local subarea = net.ReadString()
+ local boarders = net.ReadTable()
+end)
diff --git a/gamemode/core/npcmap/sv_npcmap.lua b/gamemode/core/npcmap/sv_npcmap.lua
new file mode 100644
index 0000000..8368484
--- /dev/null
+++ b/gamemode/core/npcmap/sv_npcmap.lua
@@ -0,0 +1,22 @@
+if CLIENT then error("You're not supposed to be here!") end
+local pmeta = FindMetaTable("Player")
+
+util.AddNetworkString("addmapicon")
+util.AddNetworkString("addmaparea")
+
+function pmeta:AddMapIcon(icon,subarea,position)
+ print("adding map icon")
+ net.Start("addmapicon")
+ net.WriteString(icon)
+ net.WriteString(subarea)
+ net.WriteVector(position)
+ net.Send(self)
+end
+
+function pmeta:AddMapArea(icon,subarea,bordertbl)
+ print("adding area")
+ net.Start("addmaparea")
+ net.WriteString(icon)
+ net.WriteString(subarea)
+ net.WriteTable(bordertbl)
+end
diff --git a/gamemode/shared.lua b/gamemode/shared.lua
index 8f8483f..38e63bb 100644
--- a/gamemode/shared.lua
+++ b/gamemode/shared.lua
@@ -1,10 +1,13 @@
local a = include("autolua.lua")
ART = {}
-
+a.AddLuaSHFolder("utility",true)
+a.AddMixedFolder("core",true)
a.AddLuaSHFolder("shared",true)
a.AddLuaCSFolder("client",true)
-a.AddLuaSVFolder("server",false)
+a.AddLuaSVFolder("server",true)
+a.AddMixedFolder("tools",true)
+
GM.Name = "Artery"
GM.Author = "Alexander \"Apickx\" Pickering"
@@ -60,8 +63,10 @@ end
--Add a thing to report errors to a master server
--TODO:Set up a master server to collect errors for correction
+--[[
local olderr = error
function error(str)
print("I got an error!")
olderr(str)
end
+]]
diff --git a/gamemode/shared/inventory.lua b/gamemode/shared/inventory.lua
index 7b6c9cd..006a566 100644
--- a/gamemode/shared/inventory.lua
+++ b/gamemode/shared/inventory.lua
@@ -2,6 +2,10 @@
Various functions to work with inventories
player:GetCredits()
player:SetCredits(number credits)
+
+ concommands:
+ artery_showinventory
+ artery_setcredits [playername=admin] numcredits
]]
--- Various functions to deal with inventories.
-- @module Player
@@ -45,6 +49,7 @@ if SERVER then
-- Sets the number of credits this player has. Credits are synchronized after every set
-- @param num The number of credits to set on the player
function pmeta:SetCredits(num)
+ assert(type(num) == "number","Attempted to set credits to something other than a number:" .. type(num))
self.Inventory.Credits = num
SynchCredits(self)
end
@@ -259,11 +264,12 @@ net.Receive("buyitem",function(len,ply)
ply:ChatPrint("Could not find a shop selling that!")
return false
end
- print("Found item, cost was ", cost)
+ print("Found item, cost was ", cost,"type",type(cost))
local playercreds = ply:GetCredits()
+ print("player credits:",playercreds,"type:",type(playercreds))
local tbp = ply.Inventory.Backpacks[backpack]
local canfit = invfuncs.CanFitInBackpack(tbp,j,i,item)
- print("Can it?",canfit)
+ print("Can fit?",canfit)
if playercreds < cost then
ply:ChatPrint("You don't have enough credits to buy that!")
return false
@@ -272,8 +278,9 @@ net.Receive("buyitem",function(len,ply)
ply:ChatPrint("You can't put that into your packpack there!")
return false
end
- playercreds:SetCredits(playercreds - cost)
+ ply:SetCredits(playercreds - cost)
invfuncs.PutItemInBackpack(tbp,j,i,item)
+ ply:SynchronizeInventory()
return true
end)
@@ -370,6 +377,21 @@ concommand.Add("artery_showinventory",function(ply,cmd,args)
PrintTable(ply.ClientInventory)
end)
+concommand.Add("artery_setcredits",function(ply,cmd,args)
+ if not (ply:IsValid() and ply:IsAdmin()) then return end
+ local e
+ local i = false
+ for k,v in pairs(player.GetAll()) do
+ if v:Nick() == args[1] then
+ e = v
+ i = true
+ break
+ end
+ end
+ e = e or ply
+ e:SetCredits(tonumber(args[i and 2 or 1]))
+end)
+
hook.Add( "PlayerSpawn", "artery_disable_sprint", function(ply)
ply:SetRunSpeed(ply:GetWalkSpeed())
end )
diff --git a/gamemode/shared/itemsystem/weapons/rustyaxe.lua b/gamemode/shared/itemsystem/weapons/rustyaxe.lua
index 735c3da..b26597c 100644
--- a/gamemode/shared/itemsystem/weapons/rustyaxe.lua
+++ b/gamemode/shared/itemsystem/weapons/rustyaxe.lua
@@ -49,62 +49,54 @@ item.Shape = {
--Optional, If this item can be equiped in any player slots, put them here.
item.Equipable = "Right"
---[[ returns the direction the player swung]]
-local function 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
-
-local positionset = {}
-
---[[
-local function swingarc(player,times,positions,onhit)
- local positionpoints = {}
- table.insert(positionset,positionpoints)
- local hitents = {}
- for k,v in ipairs(times) do
- timer.Simple(v,function()
- local weaponpos = positions[k] + player:GetPos()
- table.insert(positionpoints,weaponpos)
- if #positionpoints > 1 then
- local tr = util.TraceLine({
- start = positionpoints[#positionpoints-1],
- endpos = positionpoints[#positionpoints],
- })
- if tr.Hit then
- onhit(tr)
- end
- end
- end)
- end
- timer.Simple(times[#times],function()
- print("Inserted swing, drawn positions are now:")
- PrintTable(positionset)
- end)
-end
-
-hook.Add( "HUDPaint", "weaponswings", function()
- cam.Start3D() -- Start the 3D function so we can draw onto the screen.
- for k,v in pairs(positionset) do
- for i = 1,#v-1 do
- render.DrawLine( v[i], v[i+1], Color(255,0,0,255), false )
- end
- 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 )
-]]
+local swingdata = {
+ ["fwd"] = {
+ {0.011,Vector(-25,-3,-11)},
+ {0.020,Vector(-25,-1,-3)},
+ {0.031,Vector(-21,0,7)},
+ {0.040,Vector(-13,-1,16)},
+ {0.051,Vector(0,-5,22)},
+ {0.060,Vector(17,-12,19)},
+ {0.069,Vector(27,-18,11)},
+ {0.077,Vector(31,-22,2)},
+ {0.087,Vector(32,-26,-6)},
+ {0.098,Vector(32,-28,-12)},
+ {0.107,Vector(31,-29,-16)},
+ {0.117,Vector(31,-29,-17)},
+ {0.128,Vector(31,-29,-16)},
+ {0.141,Vector(31,-29,-16)},
+ },
+ ["lft"] = {
+ {0.009,Vector(-34,-25,3)},
+ {0.021,Vector(-29,-33,3)},
+ {0.031,Vector(-21,-41,2)},
+ {0.042,Vector(-9,-47,0)},
+ {0.053,Vector(5,-48,-2)},
+ {0.064,Vector(20,-44,-6)},
+ {0.075,Vector(31,-34,-10)},
+ {0.086,Vector(37,-24,-15)},
+ {0.095,Vector(39,-16,-17)},
+ {0.106,Vector(39,-10,-19)},
+ {0.116,Vector(39,-8,-20)},
+ {0.126,Vector(39,-8,-19)},
+ {0.134,Vector(39,-9,-19)},
+ {0.146,Vector(39,-10,-18)},
+ },
+ ["rig"] = {
+ {0.021,Vector(-2,9,11)},
+ {0.031,Vector(5,10,10)},
+ {0.042,Vector(12,8,9)},
+ {0.053,Vector(19,4,6)},
+ {0.062,Vector(26,-4,2)},
+ {0.072,Vector(29,-12,-4)},
+ {0.083,Vector(29,-21,-12)},
+ {0.093,Vector(25,-27,-18)},
+ {0.102,Vector(22,-30,-22)},
+ {0.113,Vector(20,-31,-25)},
+ {0.123,Vector(19,-32,-25)},
+ {0.133,Vector(19,-32,-25)},
+ },
+}
--Optional, what to do when the player clicks, and this item is in the slot in inventory. only works for items equipable in left and right
item.lastSwing = {}
@@ -114,65 +106,98 @@ item.onClick = function(self,owner)
print("returning because item.lastSwing is " .. item.lastSwing[owner], "but Curtime is",CurTime())
return end
item.lastSwing[owner] = CurTime()+1.33
- local dir = playermovedir(owner)
- local fow,rig,up = owner:GetForward(),owner:GetRight(),owner:GetUp()
+ local fwd,rig,up = owner:GetForward(),owner:GetRight(),owner:GetUp()
local movementtbl = {
["forward"] = function()
owner:SetLuaAnimation("axe_swing_up")
- timer.Simple(2.33,function() owner:StopLuaAnimation("axe_swing_up") end)
- local hits = ART.swingarc(owner,{
- 1,1.1,1.2,1.3
- },{
- fow*20 + up*26,
- fow*45 + up*6,
- fow*35 + up*-13,
- fow*20 + up*-34,
- },function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ timer.Simple(2.33,function()
+ owner:StopLuaAnimation("axe_swing_up")
+ end)
+ timer.Simple(1,function()
+ ART.TraceWeapon = true
+ end)
+ timer.Simple(1.33,function()
+ ART.TraceWeapon = false
+ end)
+
+ local times,pos = {},{}
+ for k,v in ipairs(swingdata["fwd"]) do
+ times[k] = 1 + v[1]
+ pos[k] = Vector(v[2])
+ pos[k]:Rotate(owner:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ local hits = ART.swingarc(owner,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "forward" then
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
+
end,
["backward"] = function()
end,
["left"] = function()
owner:SetLuaAnimation("axe_swing_left")
- timer.Simple(2.33,function() owner:StopLuaAnimation("axe_swing_left") end)
- local hits = ART.swingarc(owner,{
- 1,1.1,1.2,1.3
- },{
- rig*30 + up*-5,
- rig*10 + fow*30 + up*-9,
- rig*-10 + fow*30 + up*-10,
- rig*-30 + up*-15,
- },function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ timer.Simple(2.33,function()
+ owner:StopLuaAnimation("axe_swing_left")
+ end)
+ timer.Simple(1,function()
+ ART.TraceWeapon = true
+ end)
+ timer.Simple(1.33,function()
+ ART.TraceWeapon = false
+ end)
+
+ local times,pos = {},{}
+ for k,v in ipairs(swingdata["lft"]) do
+ times[k] = 1 + v[1]
+ pos[k] = Vector(v[2])
+ pos[k]:Rotate(owner:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ local hits = ART.swingarc(owner,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "left" then
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
["right"] = function()
owner:SetLuaAnimation("axe_swing_right")
- timer.Simple(2.33,function() owner:StopLuaAnimation("axe_swing_right") end)
- local hits = ART.swingarc(owner,{
- 1,1.1,1.2,1.3
- },{
- rig*-30 + up*-5,
- rig*-10 + fow*30 + up*-9,
- rig*10 + fow*30 + up*-10,
- rig*30 + up*-15,
- },function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ timer.Simple(2.33,function()
+ owner:StopLuaAnimation("axe_swing_right")
+ end)
+ timer.Simple(1,function()
+ ART.TraceWeapon = true
+ end)
+ timer.Simple(1.33,function()
+ ART.TraceWeapon = false
+ end)
+
+ local times,pos = {},{}
+ for k,v in ipairs(swingdata["rig"]) do
+ times[k] = 1 + v[1]
+ pos[k] = Vector(v[2])
+ pos[k]:Rotate(owner:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ local hits = ART.swingarc(owner,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "right" then
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
}
- movementtbl[playermovedir(owner)]()
+ movementtbl[ART.playermovedir(owner)]()
end
--Optional, if we should do something special on equip(like draw the PAC for this weapon)
diff --git a/gamemode/shared/itemsystem/weapons/scraphammer.lua b/gamemode/shared/itemsystem/weapons/scraphammer.lua
index 9ec7ac9..299d4e2 100644
--- a/gamemode/shared/itemsystem/weapons/scraphammer.lua
+++ b/gamemode/shared/itemsystem/weapons/scraphammer.lua
@@ -26,6 +26,7 @@ function item.GetOptions(self)
local options = {}
options["test"] = function() print("You pressed test!") end
options["toste"] = function() print("You pressed toste!") end
+ options["Drop"] = ART.DropItem(self)
return options
end
@@ -60,7 +61,64 @@ item.Shape = {
--Optional, If this item can be equiped in any player slots, put them here.
item.Equipable = "Right"
-
+local swingdata = {
+ ["fwd"] = {
+ {0.007,Vector(-27,1,9)},
+ {0.014,Vector(-20,3,16)},
+ {0.020,Vector(-11,6,22)},
+ {0.027,Vector(0,7,26)},
+ {0.032,Vector(15,7,25)},
+ {0.039,Vector(28,6,21)},
+ {0.045,Vector(38,4,14)},
+ {0.052,Vector(46,0,3)},
+ {0.059,Vector(50,-3,-6)},
+ {0.065,Vector(52,-6,-15)},
+ {0.072,Vector(52,-8,-22)},
+ {0.078,Vector(51,-10,-28)},
+ {0.084,Vector(50,-11,-31)},
+ {0.091,Vector(50,-11,-32)},
+ {0.097,Vector(50,-11,-32)}
+ },
+ ["lft"] = {
+ {0.007,Vector(-6,24,2)},
+ {0.014,Vector(-1,26,2)},
+ {0.020,Vector(5,28,1)},
+ {0.027,Vector(12,28,-1)},
+ {0.035,Vector(19,27,-4)},
+ {0.042,Vector(27,24,-7)},
+ {0.048,Vector(37,17,-13)},
+ {0.055,Vector(42,12,-17)},
+ {0.061,Vector(45,5,-20)},
+ {0.068,Vector(48,-2,-23)},
+ {0.075,Vector(49,-8,-25)},
+ {0.084,Vector(49,-14,-26)},
+ {0.091,Vector(49,-19,-27)},
+ {0.097,Vector(48,-22,-27)},
+ {0.104,Vector(48,-25,-27)},
+ {0.110,Vector(48,-26,-27)},
+ {0.117,Vector(48,-27,-27)},
+ {0.123,Vector(48,-26,-27)},
+ {0.131,Vector(48,-26,-27)}
+ },
+ ["rig"] = {
+ {0.009,Vector(-3,25,2)},
+ {0.017,Vector(3,27,1)},
+ {0.025,Vector(11,28,-1)},
+ {0.032,Vector(20,27,-4)},
+ {0.040,Vector(28,24,-7)},
+ {0.051,Vector(36,19,-12)},
+ {0.059,Vector(42,11,-17)},
+ {0.067,Vector(47,2,-22)},
+ {0.075,Vector(49,-5,-25)},
+ {0.083,Vector(49,-13,-27)},
+ {0.090,Vector(49,-19,-28)},
+ {0.098,Vector(48,-24,-28)},
+ {0.106,Vector(48,-27,-28)},
+ {0.114,Vector(48,-28,-28)},
+ {0.121,Vector(48,-27,-28)},
+ {0.129,Vector(48,-27,-27)}
+ },
+}
--Optional, what to do when the player clicks, and this item is in the slot in inventory. only works for items equipable in left and right
item.lastSwing = {}
@@ -70,26 +128,30 @@ item.onClick = function(self,owner)
print("returning because item.lastSwing is " .. item.lastSwing[owner], "but Curtime is",CurTime())
return end
item.lastSwing[owner] = CurTime()+1.33
- local fow,rig,up = owner:GetForward(),owner:GetRight(),owner:GetUp()
+ local fwd,rig,up = owner:GetForward(),owner:GetRight(),owner:GetUp()
local movementtbl = {
["forward"] = function()
owner:SetLuaAnimation("hammer_swing_up")
timer.Simple(2.33,function()
owner:StopLuaAnimation("hammer_swing_up")
end)
- local hits = ART.swingarc(owner,{
- 1,1.1,1.2,1.3
- },{
- fow*40 + up*26,
- fow*60 + up*6,
- fow*55 + up*-13,
- fow*40 + up*-34,
- },function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+
+ local times,pos = {},{}
+ for k,v in ipairs(swingdata["fwd"]) do
+ times[k] = 1 + v[1]
+ pos[k] = Vector(v[2])
+ pos[k]:Rotate(owner:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ local hits = ART.swingarc(owner,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "forward" then
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
+
end,
["backward"] = function()
@@ -99,18 +161,21 @@ item.onClick = function(self,owner)
timer.Simple(2.33,function()
owner:StopLuaAnimation("hammer_swing_left")
end)
- local hits = ART.swingarc(owner,{
- 1,1.1,1.2,1.3
- },{
- rig*30 + up*-5,
- rig*20 + fow*40 + up*-9,
- rig*-20 + fow*40 + up*-10,
- rig*-30 + up*-15,
- },function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
- tr.Entity:TakeDamage(10, owner, owner:GetActiveWeapon())
+
+ local times,pos = {},{}
+ for k,v in ipairs(swingdata["lft"]) do
+ times[k] = 1 + v[1]
+ pos[k] = Vector(v[2])
+ pos[k]:Rotate(owner:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ local hits = ART.swingarc(owner,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "left" then
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
["right"] = function()
@@ -118,18 +183,21 @@ item.onClick = function(self,owner)
timer.Simple(2.33,function()
owner:StopLuaAnimation("hammer_swing_right")
end)
- local hits = ART.swingarc(owner,{
- 1,1.1,1.2,1.3
- },{
- rig*-30 + up*-5,
- rig*-10 + fow*40 + up*-9,
- rig*10 + fow*40 + up*-10,
- rig*30 + up*-15,
- },function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+
+ local times,pos = {},{}
+ for k,v in ipairs(swingdata["rig"]) do
+ times[k] = 1 + v[1]
+ pos[k] = Vector(v[2])
+ pos[k]:Rotate(owner:GetAimVector():Angle())
+ end
+ if pos[1] == nil then return end
+ local hits = ART.swingarc(owner,times,pos,function(tr)
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "right" then
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
}
diff --git a/gamemode/shared/itemsystem/weapons/seratedknife.lua b/gamemode/shared/itemsystem/weapons/seratedknife.lua
index e57351d..2daec36 100644
--- a/gamemode/shared/itemsystem/weapons/seratedknife.lua
+++ b/gamemode/shared/itemsystem/weapons/seratedknife.lua
@@ -26,6 +26,7 @@ function item.GetOptions(self)
local options = {}
options["test"] = function() print("You pressed test!") end
options["toste"] = function() print("You pressed toste!") end
+ options["Drop"] = ART.DropItem(self)
return options
end
@@ -58,6 +59,14 @@ item.Shape = {
--Optional, If this item can be equiped in any player slots, put them here.
item.Equipable = "Right"
+local function attacktrace(tr,owner)
+ if not tr.Hit then return end
+ if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
+ end
+end
+
+
--Optional, what to do when the player clicks, and this item is in the slot in inventory. only works for items equipable in left and right
item.lastSwing = {}
local animationtime = 1.833333
@@ -82,10 +91,14 @@ item.onClick = function(self,owner)
fow*35 + up*45,
fow*20 + up*30,
},function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
- tr.Entity:TakeDamage(4, owner, owner:GetActiveWeapon())
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "forward" then
+ print("Entity blocked!")
+ ART.ApplyEffect(owner,"weapon_blocked")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ print("Got past blocking, it was",tr.Entity.Blocking)
+ tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
["backward"] = function()
@@ -101,10 +114,13 @@ item.onClick = function(self,owner)
fow*25 + up*70,
fow*15 + up*90,
},function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
- tr.Entity:TakeDamage(4, owner, owner:GetActiveWeapon())
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "backward" then
+ print("Entity blocked!")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ print("Got past blocking, it was",tr.Entity.Blocking)
+ tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
["left"] = function()
@@ -120,10 +136,13 @@ item.onClick = function(self,owner)
rig*-10 + fow*30 + up*54,
rig*-30 + up*50,
},function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
- tr.Entity:TakeDamage(4, owner, owner:GetActiveWeapon())
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "left" then
+ print("Entity blocked!")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ print("Got past blocking, it was",tr.Entity.Blocking)
+ tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
["right"] = function()
@@ -139,10 +158,13 @@ item.onClick = function(self,owner)
rig*10 + fow*30 + up*54,
rig*30 + up*50,
},function(tr)
- if tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
- tr.Entity:TakeDamage(4, owner, owner:GetActiveWeapon())
+ if not tr.Hit then return end
+ if tr.Entity.Blocking ~= nil and tr.Entity.Blocking == "right" then
+ print("Entity blocked!")
+ elseif tr.Entity.TakeDamage ~= nil and tr.Entity ~= owner then
+ print("Got past blocking, it was",tr.Entity.Blocking)
+ tr.Entity:TakeDamage(5, owner, owner:GetActiveWeapon())
end
- print("Hit",tr.Entity)
end)
end,
}
diff --git a/gamemode/shared/itemsystem/weapons_common.lua b/gamemode/shared/itemsystem/weapons_common.lua
index a7679a9..6f553fa 100644
--- a/gamemode/shared/itemsystem/weapons_common.lua
+++ b/gamemode/shared/itemsystem/weapons_common.lua
@@ -29,34 +29,28 @@ local positionset = {}
-- @param onhit A function to call on any entities that were hit in the swing of the weapon.
function ART.swingarc(player,times,positions,onhit)
local positionpoints = {}
- --[[
- local ea = player:EyeAngles()
- for k,v in pairs(positions) do
- print("Position that was at ", positions[k])
- positions[k].z = positions[k].z * math.sin(ea.pitch+90)
- print("Is now at",positions[k])
- end
- ]]
table.insert(positionset,positionpoints)
- local hitents = {}
for k,v in ipairs(times) do
timer.Simple(v,function()
+ ART.TraceWeapon = true
+ ART.TraceStart = CurTime()
+ print("positions[k]",positions[k],"playerpos",player:GetPos(),"add",Vector(0,0,64))
local weaponpos = positions[k] + player:GetPos() + Vector(0,0,64)
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],
})
- if tr.Hit then
- onhit(tr)
- end
+ onhit(tr)
end
end)
end
timer.Simple(times[#times],function()
print("Inserted swing, drawn positions are now:")
PrintTable(positionset)
+ ART.TraceWeapon = false
end)
end
@@ -65,6 +59,7 @@ hook.Add( "HUDPaint", "weaponswings", function()
for k,v in pairs(positionset) do
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
end
--render.SetMaterial( material ) -- Tell render what material we want, in this case the flash from the gravgun
diff --git a/gamemode/shared/loadnpcs.lua b/gamemode/shared/loadnpcs.lua
index bff5135..3e1861f 100644
--- a/gamemode/shared/loadnpcs.lua
+++ b/gamemode/shared/loadnpcs.lua
@@ -4,11 +4,13 @@ local f = include("concommands.lua")
ART = ART or {}
local npcs = {}
+local autocompletef
function ART.RegisterNPC(npc)
assert(npc ~= nil, "Attempted to register a nil npc")
assert(npc.Name ~= nil, "Attempted to register an npc without a name")
npcs[npc.Name] = npc
+ autocompletef = f.AutocompleteFunction(npcs)
end
function ART.CreateNPCByName(npcname, pos)
@@ -20,9 +22,10 @@ function ART.CreateNPCByName(npcname, pos)
npc[k] = v
end
npc:Spawn()
+ return npc
end
-local autocompletef
+
if SERVER then
autocompletef = nil
else
diff --git a/gamemode/shared/npcsystem/blockingdummy.lua b/gamemode/shared/npcsystem/blockingdummy.lua
new file mode 100644
index 0000000..5c6008c
--- /dev/null
+++ b/gamemode/shared/npcsystem/blockingdummy.lua
@@ -0,0 +1,105 @@
+local NPC = {}
+NPC.Name = "Blocking Training Dummy"
+NPC.Desc = "A man made of straw. His dream is to have a brain."
+NPC.Class = "Ambient" --Ambient, Agressive, Boss
+NPC.Model = "models/headcrab.mdl"
+
+NPC.Stats = {
+ ["Vitality"] = 100000,
+ ["Speed"] = 400,
+ ["AwareDist"] = 1000,
+ ["Accel"] = 100,
+ ["Decel"] = 200,
+ ["Step"] = 20, --Step height
+ ["Hull"] = HULL_TINY
+}
+
+--Some npc's like birds have diffent names for their idle sequences
+NPC.IdleSequences = {
+ [0] = "lookaround",
+ [1] = "Idle01",
+}
+
+--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100
+
+NPC.Drops = {
+}
+
+--Attacks should be formated as [i]={function attackpriority() = function doattack()}
+local checknothing = function(self,ply)
+ return 1
+end
+
+local donothing = function(self,ply)
+end
+NPC.Attacks = {
+ [1] = {--run away from the player
+ [checknothing] = donothing
+ },
+}
+
+--A function that takes a position and returns true if this is an acceptable place to spawn
+function NPC:SpawnLocations(pos)
+ return true
+end
+
+--The entity that is this npc's current target, if it has one. Nil otherwise
+NPC.Target = nil
+
+--All enemies that this NPC is aware of
+NPC.AwareEnemies = {}
+--Attack priority is a fucntion that takes a player, and returns an int describing it's prority to attack (higher = more important) NPC will always attack the player with the highest priority
+function NPC:AttackPriority(ply)
+ if not ply then return 0 end
+ return 1
+end
+
+--What to replace the ENT:RunBehaviour with
+function NPC:Act(deltat)
+end
+
+--What to replace ENT:OnStuck with
+function NPC:Stuck()
+
+end
+
+local blockorder = {
+ "forward",
+ "right",
+ "backward",
+ "left"
+}
+local cursor = 0
+function NPC:OnDammage(ammount)
+ self.Blocking = blockorder[cursor + 1]
+ cursor = (cursor + 1) % 4
+ print("A dummy was hit for",ammount:GetDamage(),"!")
+ print("Blocking is now",self.Blocking)
+end
+
+--These are just here to tell the editors/develoeprs what functions are available.. dont un-comment them out, as this could affect all the items.
+/*
+function NPC:OnSpawn()
+end
+
+--If we need to do more than just reduce health on dammage
+function NPC:OnDammage(ammount)
+end
+
+--If we need to do more than just drop items on death
+function NPC:OnDeath()
+end
+
+--A particular spell was cast on this npc by player
+function NPC:OnSpell(spell, player)
+end
+
+function NPC:OnFindEnemy(enemy)
+end
+
+--Called when the npc is attacking anything with any attack
+function NPC:OnAttack(target)
+end
+*/
+
+ART.RegisterNPC(NPC)
diff --git a/gamemode/shared/npcsystem/dummy.lua b/gamemode/shared/npcsystem/dummy.lua
new file mode 100644
index 0000000..869dd0e
--- /dev/null
+++ b/gamemode/shared/npcsystem/dummy.lua
@@ -0,0 +1,95 @@
+local NPC = {}
+NPC.Name = "Training Dummy"
+NPC.Desc = "A man made of straw. His dream is to have a brain."
+NPC.Class = "Ambient" --Ambient, Agressive, Boss
+NPC.Model = "models/headcrab.mdl"
+
+NPC.Stats = {
+ ["Vitality"] = 100000,
+ ["Speed"] = 400,
+ ["AwareDist"] = 1000,
+ ["Accel"] = 100,
+ ["Decel"] = 200,
+ ["Step"] = 20, --Step height
+ ["Hull"] = HULL_TINY
+}
+
+--Some npc's like birds have diffent names for their idle sequences
+NPC.IdleSequences = {
+ [0] = "lookaround",
+ [1] = "Idle01",
+}
+
+--Drops should be formated as [index]={["item name"], percent_drop} where percent_drop is a number from 0 to 100
+
+NPC.Drops = {
+}
+
+--Attacks should be formated as [i]={function attackpriority() = function doattack()}
+local checknothing = function(self,ply)
+ return 1
+end
+
+local donothing = function(self,ply)
+end
+NPC.Attacks = {
+ [1] = {--run away from the player
+ [checknothing] = donothing
+ },
+}
+
+--A function that takes a position and returns true if this is an acceptable place to spawn
+function NPC:SpawnLocations(pos)
+ return true
+end
+
+--The entity that is this npc's current target, if it has one. Nil otherwise
+NPC.Target = nil
+
+--All enemies that this NPC is aware of
+NPC.AwareEnemies = {}
+--Attack priority is a fucntion that takes a player, and returns an int describing it's prority to attack (higher = more important) NPC will always attack the player with the highest priority
+function NPC:AttackPriority(ply)
+ if not ply then return 0 end
+ return 1
+end
+
+--What to replace the ENT:RunBehaviour with
+function NPC:Act(deltat)
+end
+
+--What to replace ENT:OnStuck with
+function NPC:Stuck()
+
+end
+
+function NPC:OnDammage(ammount)
+ print("A dummy was hit for",ammount:GetDamage(),"!")
+end
+
+--These are just here to tell the editors/develoeprs what functions are available.. dont un-comment them out, as this could affect all the items.
+/*
+function NPC:OnSpawn()
+end
+
+--If we need to do more than just reduce health on dammage
+function NPC:OnDammage(ammount)
+end
+
+--If we need to do more than just drop items on death
+function NPC:OnDeath()
+end
+
+--A particular spell was cast on this npc by player
+function NPC:OnSpell(spell, player)
+end
+
+function NPC:OnFindEnemy(enemy)
+end
+
+--Called when the npc is attacking anything with any attack
+function NPC:OnAttack(target)
+end
+*/
+
+ART.RegisterNPC(NPC)
diff --git a/gamemode/shared/sh_npcmap.lua b/gamemode/shared/sh_npcmap.lua
deleted file mode 100644
index 5c6d93c..0000000
--- a/gamemode/shared/sh_npcmap.lua
+++ /dev/null
@@ -1,27 +0,0 @@
-
-local pmeta = FindMetaTable("Player")
-
-if SERVER then
- util.AddNetworkString("addmapicon")
-end
-
-function pmeta:AddMapIcon(icon,position)
- print("adding map icon")
- net.Start("addmapicon")
- net.WriteString(icon)
- net.WriteVector(position)
- net.Send(self)
-end
-
-if CLIENT then
- net.Receive("addmapicon",function()
- print("got recieve for map icon")
- LocalPlayer().MapIcons = LocalPlayer().MapIcons or {}
- local matstr = net.ReadString()
- local matpos = net.ReadVector()
- table.insert(LocalPlayer().MapIcons,{
- ["material"] = Material(matstr),
- ["pos"] = matpos,
- })
- end)
-end
diff --git a/gamemode/shared/sh_pac.lua b/gamemode/shared/sh_pac.lua
index 1ab9f88..1d4da41 100644
--- a/gamemode/shared/sh_pac.lua
+++ b/gamemode/shared/sh_pac.lua
@@ -2,6 +2,7 @@
All the functions related to networking pac's
]]
if CLIENT then
+ local what
local function applypac(who,pacname)
local pactxt = file.Read("artery/pacs/"..pacname..".txt","DATA")
print("got pac txt",pactxt)
@@ -26,9 +27,37 @@ if CLIENT then
print("who is",who)
who:AttachPACPart(pactbl)
print("Pac Equiped!")
+
+ what = who:FindPACPart(pactbl, "ball")
+ print("what was", what)
+ if what ~= nil then
+ print("What's position:")
+ for k,v in pairs(what) do
+ print(k,":",v)
+ end
+ print(what:GetDrawPosition(),type(what:GetDrawPosition()))
+ end
end
end
+ local RecordTrace = false
+ local swingtime
+ hook.Add("Tick","weapon_trace",function()
+ if what ~= nil and ART.TraceWeapon and RecordTrace then
+ local pos = what:GetDrawPosition()
+ local ppos = LocalPlayer():GetPos()
+ for k = 1,3 do pos[k] = pos[k] - ppos[k] end -- Now is a local vector, player is the origin
+ print(string.format("{%1.3f,Vector(%d,%d,%d)},",swingtime/1000,pos[1],pos[2],pos[3]-64))
+ swingtime = swingtime + util.TimerCycle()
+ else
+ swingtime = util.TimerCycle()
+ end
+ end)
+
+ concommand.Add("artery_dev_traceweapons",function(ply,cmd,args)
+ RecordTrace = args[1] == "1"
+ end)
+
local function removepac(who,pacname)
local pactxt = file.Read("artery/pacs/"..pacname..".txt","DATA")
assert(pactxt ~= nil, "Attempted to remove a pac that dosn't exist")
diff --git a/gamemode/shared/shop.lua b/gamemode/shared/shop.lua
index b188e7c..c330fb3 100644
--- a/gamemode/shared/shop.lua
+++ b/gamemode/shared/shop.lua
@@ -1,3 +1,13 @@
+--[[
+ Displays shop npc's interfaces
+
+ public functions:
+ (sv)ART.OpenShop(shoptbl, ply) :: nil
+ (sv)ART.CreateShop(npctbl) :: nil
+ net messages:
+ art_openshop
+]]
+
local ivf = include("inventory_common.lua")
ART = ART or {}
@@ -34,10 +44,8 @@ end
if SERVER then return end
local w,h = ScrW(),ScrH()
-function DrawShopItemOnDPanel(dp,item)
+local function DrawShopItemOnDPanel(dp,itemtbl,cost)
--An item is a string, and int cost
- local itemtbl = ART.GetItemByName(item[1])
- local cost = item[2]
local shape = itemtbl.Shape
local twidth,theight = 0,#shape
@@ -50,7 +58,7 @@ function DrawShopItemOnDPanel(dp,item)
backgrid:SetPos( 10, 30 )
backgrid:SetCols( twidth )
backgrid:SetColWide( theight )
- backgrid:Dock(FILL)
+ backgrid:Dock(LEFT)
local shopicon = vgui.Create( "DImageButton", dp )
shopicon:SetSize(slotsize * twidth, slotsize * theight)
@@ -65,7 +73,10 @@ function DrawShopItemOnDPanel(dp,item)
if itemtbl.DoOnPanel then
itemtbl.DoOnPanel(shopicon)
end
- --invicon.Paint = function(self, w, h) draw.RoundedBox(4, 0,0,w,h,Color(0,100,0)) end
+ shopicon.Paint = function(self, w, h)
+ surface.SetDrawColor( 0, 0, 0, 255 )
+ surface.DrawOutlinedRect( 0, 0, w, h)
+ end
shopicon.DoClick = function()
print("You cliked me!")
end
@@ -92,16 +103,41 @@ function DrawShopItemOnDPanel(dp,item)
print("Found false spot:",k,i)
local emptyslot = vgui.Create("DPanel", dp)
emptyslot:SetSize(slotsize,slotsize)
- emptyslot:SetPos(slotsize * (i - 1), slotsize * (k - 1))
+ emptyslot:SetPos(slotsize * (i - 1) + 2, slotsize * (k - 1) + 2)
end
end
end
end
-function DrawShopOnDPanel(dp,items)
+local slotsize = math.Round(w / 32)
+
+local function DrawShopOnDPanel(dp,items)
--This gets pretty involved, lets try to not make it a clusterfuck.
- DrawShopItemOnDPanel(dp,items[1])
+ dp.Paint = function(self, w, h) draw.RoundedBox(4, 0,0,w,h,Color(100,0,0)) end
+ print("dp",dp)
+ local scrollpanel = vgui.Create( "DScrollPanel",dp )
+ print("scollpanel",scrollpanel)
+ scrollpanel.Paint = function(self, w, h) draw.RoundedBox(4, 0,0,w,h,Color(0,0,100)) end
+ scrollpanel:Dock(FILL)
+ for k,v in pairs(items) do
+ local itemtbl = ART.GetItemByName(v[1])
+ local invpanel = vgui.Create( "DPanel", scollpanel)
+ invpanel.Paint = function(self, w, h)
+ draw.RoundedBox(4, 1,1,w-4,h-4,Color(50,50,50))
+ draw.RoundedBox(4, 2,2,w-5,h-5,Color(100,100,100))
+ end
+ print("invpanel",invpanel)
+ DrawShopItemOnDPanel(invpanel,itemtbl,v[2])
+ scrollpanel:AddItem(invpanel)
+ invpanel:Dock(TOP)
+ local x,_ = invpanel:GetSize()
+ print("item is",v)
+ PrintTable(v)
+ invpanel:SetSize(x,slotsize*(#itemtbl.Shape) + 4)
+ invpanel:Dock(TOP)
+
+ end
end
diff --git a/gamemode/tools/markarea/sh_markarea.lua b/gamemode/tools/markarea/sh_markarea.lua
new file mode 100644
index 0000000..217680a
--- /dev/null
+++ b/gamemode/tools/markarea/sh_markarea.lua
@@ -0,0 +1,4 @@
+--[[
+ Allows you to easily mark areas of the map
+]]
+print("hello from markarea.lua")
diff --git a/gamemode/utility/mapfuncs.lua b/gamemode/utility/mapfuncs.lua
new file mode 100644
index 0000000..579da5f
--- /dev/null
+++ b/gamemode/utility/mapfuncs.lua
@@ -0,0 +1,25 @@
+local f = {}
+
+function f.foreach(tbl,func)
+ for k,v in pairs(tbl) do func(v,k) end
+end
+
+function f.take(tbl,num)
+ local ntbl = {}
+ for i=1,num do
+ ntbl[i] = tbl[i]
+ end
+ return ntbl
+end
+
+function f.takeRight(tbl,num)
+ local ntbl = {}
+ for i = #tbl - num, #tbl do
+ ntbl[#ntbl+1] = tbl[i]
+ end
+ return ntbl
+end
+
+
+
+return f