diff options
| author | Bob Blackmon <bob.blackmon@ymail.com> | 2017-04-02 23:21:08 -0400 |
|---|---|---|
| committer | Bob Blackmon <bob.blackmon@ymail.com> | 2017-04-02 23:21:08 -0400 |
| commit | 49e018aee0b82e805660e819d7b7647d8ac9c07c (patch) | |
| tree | 40df2d15206b7fe30d62caf30be17c40b2fa5457 /lua/weapons/weapon_zone_designator.lua | |
| parent | b13ed9659114f5957f00f27ee6fe0f2d353d18c5 (diff) | |
| download | zones-49e018aee0b82e805660e819d7b7647d8ac9c07c.tar.gz zones-49e018aee0b82e805660e819d7b7647d8ac9c07c.tar.bz2 zones-49e018aee0b82e805660e819d7b7647d8ac9c07c.zip | |
Changed folder
Diffstat (limited to 'lua/weapons/weapon_zone_designator.lua')
| -rw-r--r-- | lua/weapons/weapon_zone_designator.lua | 703 |
1 files changed, 703 insertions, 0 deletions
diff --git a/lua/weapons/weapon_zone_designator.lua b/lua/weapons/weapon_zone_designator.lua new file mode 100644 index 0000000..fd2c0c5 --- /dev/null +++ b/lua/weapons/weapon_zone_designator.lua @@ -0,0 +1,703 @@ + +if CLIENT then + CreateClientConVar("zone_tall",200,false,true) + CreateClientConVar("zone_class","",false,true) + CreateClientConVar("zone_editmode",1,false,true) + CreateClientConVar("zone_filter",0,false,true) + + surface.CreateFont( "zones_save", { + font = "Roboto", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name + size = 20, + weight = 1000, + } ) + surface.CreateFont( "zones_screen", { + font = "Arial", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name + size = 20, + weight = 1000, + + } ) +else + concommand.Add("zone_swep",function(p,c,a) + if p:IsAdmin() then + p:Give("weapon_zone_designator") + end + end) +end + +if engine.ActiveGamemode() == "terrortown" then + SWEP.Base = "weapon_tttbase" + SWEP.Kind = WEAPON_EQUIP2 +end + + +SWEP.NoSights = true + +SWEP.PrintName = "Zone Designator" +SWEP.Author = "Bobblehead" +SWEP.Purpose = "Creates zones. Reload for menu. Right click to remove a point/zone." + +SWEP.Slot = 5 +SWEP.SlotPos = 5 + +SWEP.Spawnable = true +SWEP.AdminOnly = true + +SWEP.HoldType = "pistol" +SWEP.ViewModelFOV = 51 +SWEP.ViewModelFlip = false +SWEP.UseHands = true +SWEP.ViewModel = "models/weapons/c_toolgun.mdl" +SWEP.WorldModel = "models/weapons/w_toolgun.mdl" +SWEP.AutoSwitchFrom = true +SWEP.AutoSwitchTo = true + +SWEP.Primary.ClipSize = -1 +SWEP.Primary.DefaultClip = -1 +SWEP.Primary.Automatic = false +SWEP.Primary.Delay = .5 +SWEP.Primary.Ammo = "none" + +SWEP.Secondary.ClipSize = -1 +SWEP.Secondary.DefaultClip = -1 +SWEP.Secondary.Automatic = false +SWEP.Secondary.Ammo = "none" + + +function SWEP:SetupDataTables() + self:NetworkVar("Float",0,"Tall") + self:NetworkVar("String",0,"ZoneClass") + self:NetworkVar("Entity",0,"CurrentPoint") + self:NetworkVar("Int",0,"Mode") + +end + +function SWEP:Initialize() + + self:SetTall(150) + self:SetMode(1) + + self:SetCurrentPoint(NULL) +end + +function SWEP:Deploy() + if SERVER then + local points = ents.FindByClass("ent_zone_point") + local ct = 0 + for k,v in pairs(zones.List) do + for k2,v2 in pairs(v.points)do + for k3, v3 in pairs(v2) do + ct = ct + 1 + end + end + end + if #points != ct then + zones.CreatePointEnts(points) + end + end +end + +function SWEP:Holster() + if SERVER then + local none = true + for k, ply in pairs(player.GetAll()) do + if ply == self.Owner then continue end + local wep = ply:GetActiveWeapon() + if IsValid(wep) and wep:GetClass() == "weapon_zone_designator" then + none = false + break + end + end + if none then + for k,v in pairs(ents.FindByClass("ent_zone_point"))do + v:Remove() + end + end + + self:SetCurrentPoint(NULL) + + return true + end +end + +function SWEP:DrawHUD() + local z,id = LocalPlayer():GetCurrentZone(GetConVarNumber("zone_filter") == 1 and self:GetZoneClass() or nil) + z = z and z.class.."(# "..id..")" or "None" + draw.SimpleText("Current Zone: "..z, "DermaLarge", 100,100) +end + +function SWEP:PrimaryAttack() + + + self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) + + if SERVER then + self.Owner:EmitSound("buttons/button15.wav") + end + + self:UpdateSettings() + local mode = self:GetMode() + + if mode == 1 then //Create + if CLIENT then return end + self:PlacePoint() + elseif mode == 2 then //Merge + if CLIENT then return end + self:MergeZones() + + elseif mode == 3 then //Edit + local curr = self:GetCurrentPoint() + + if IsValid(curr) then + if CLIENT then return end + local next = curr + repeat + + next.Resizing = nil + + next = next:GetNext() + + until ( next == curr ) + + zones.List[curr:GetZoneID()].height[curr:GetAreaNumber()] = curr:GetTall() + zones.CalcBounds(zones.List[id]) + + self:SetCurrentPoint(NULL) + + elseif CLIENT then + local tr = self.Owner:GetEyeTrace() + if !tr.HitWorld and IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" then + zones.ShowOptions(tr.Entity:GetZoneID()) + end + + end + + elseif mode == 4 then + if CLIENT then return end + + local curr = self:GetCurrentPoint() + local tr = self.Owner:GetEyeTrace() + + if !tr.HitWorld and IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" then + + self:SetCurrentPoint(tr.Entity) + + elseif IsValid(curr) then + + local id,areanum = curr:GetZoneID(), curr:GetAreaNumber() + local next = curr:GetNext() + + local new = ents.Create("ent_zone_point") + local p = curr:GetPos() + tr.HitPos.z = p.z + new:SetPos(tr.HitPos) + curr:SetNext(new) + -- self:GetCurrentPoint():DeleteOnRemove(new) + + new.LastPoint = self:GetCurrentPoint() + self:SetCurrentPoint(new) + new:SetTall(curr:GetTall()) + new:SetZoneClass(curr:GetZoneClass()) + new:SetZoneID(id) + new:SetAreaNumber(areanum) + new:Spawn() + new:SetNext(next) + next.LastPoint = new + + + local n = new + local pts = {} + repeat + pts[#pts+1] = n:GetPos() - Vector(0,0,2) + n = n:GetNext() + until (n == new) + + + zones.List[id].points[areanum] = pts + + zones.CalcBounds(zones.List[id]) + + zones.Sync() + + end + + end + +end + +function SWEP:SecondaryAttack() + self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) + + if CLIENT then return end + + self.Owner:EmitSound("buttons/button16.wav") + + local tr = self.Owner:GetEyeTrace() + local mode = self:GetMode() + + if mode == 1 then //delete + + if !tr.HitWorld and IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" then + local point = tr.Entity + local last = point.LastPoint + + local id = point:GetZoneID() + if id != -1 then + + if #zones.List[id].points > 1 then + id = select(2,zones.Split(id, point:GetAreaNumber())) + end + + zones.Remove(id) + + end + + point:Remove() + + self:SetCurrentPoint(last) + + elseif self:GetCurrentPoint():IsValid() then + local point, last = self:GetCurrentPoint(), self:GetCurrentPoint().LastPoint + point:Remove() + self:SetCurrentPoint(last or NULL) + end + + elseif mode == 2 then //split + + if !tr.HitWorld and IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" then + local point = tr.Entity + local id = point:GetZoneID() + + if #zones.List[id].points == 1 then + return + end + + local zone, newid = zones.Split(id, point:GetAreaNumber()) + + local next = point + repeat + + next:SetZoneID(newid) + next:SetAreaNumber(next:GetAreaNumber() - #zones.List[id].points) + + next = next:GetNext() + + until ( next == point ) + + end + + elseif mode == 3 then //resize + local curr = self:GetCurrentPoint() + + if IsValid(curr) then + + local next = curr + repeat + + next.Resizing = nil + + next = next:GetNext() + + until ( next == curr ) + + zones.List[curr:GetZoneID()].height[curr:GetAreaNumber()] = curr:GetTall() + zones.CalcBounds(zones.List[curr:GetZoneID()]) + + zones.Sync() + + self:SetCurrentPoint(NULL) + + else + if !tr.HitWorld and IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" then + local next = tr.Entity + repeat + next.Resizing = self.Owner + + next = next:GetNext() + + + until ( next == tr.Entity ) + + self:SetCurrentPoint(tr.Entity) + end + end + + elseif mode == 4 then //Remove a point + + if !tr.HitWorld and IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" or IsValid(self:GetCurrentPoint()) then + + local hit = tr.Entity:IsValid() and tr.Entity or self:GetCurrentPoint() + local id,areanum = hit:GetZoneID(), hit:GetAreaNumber() + + if #zones.List[id].points[areanum] > 3 then + + local last = hit.LastPoint + local next = hit:GetNext() + + next.LastPoint = last + last:SetNext(next) + + hit:SetNext(NULL) + hit.LastPoint = nil + hit:Remove() + + local n = next + local pts = {} + repeat + pts[#pts+1] = n:GetPos() - Vector(0,0,2) + n = n:GetNext() + until (n == next) + + zones.List[id].points[areanum] = pts + + zones.CalcBounds(zones.List[id]) + + zones.Sync() + + self:SetCurrentPoint(last) + + end + + end + + end + + +end + +local mx,my +if CLIENT then + mx, my = ScrW()/2, ScrH()/2 +end + +function SWEP:Reload() --show menu. + + self:UpdateSettings() + if SERVER then + if game.SinglePlayer() then + self:CallOnClient("Reload") + end + return + end + + if IsValid(self.frame) then return end + + input.SetCursorPos(mx,my) + + self:OpenMenu() + +end + +function SWEP:PlacePoint() --mode == 1 + local tr = self.Owner:GetEyeTrace() + if tr.HitWorld then + + local next = ents.Create("ent_zone_point") + + if IsValid(self:GetCurrentPoint()) then + local p = self:GetCurrentPoint():GetPos() + tr.HitPos.z = p.z + next:SetPos(tr.HitPos) + self:GetCurrentPoint():SetNext(next) + -- self:GetCurrentPoint():DeleteOnRemove(next) + else + next:SetPos(tr.HitPos+Vector(0,0,1)) + end + + next.LastPoint = self:GetCurrentPoint() + self:SetCurrentPoint(next) + next:SetTall(self:GetTall()) + next:SetZoneClass(self:GetZoneClass()) + next:SetZoneID(-1) + next:SetAreaNumber(1) + next:Spawn() + + elseif tr.Entity:IsValid() and tr.Entity:GetClass() == "ent_zone_point" and tr.Entity != self:GetCurrentPoint() then + if IsValid(self:GetCurrentPoint()) then + local next = tr.Entity + if !IsValid(next.LastPoint) then + + self:GetCurrentPoint():SetNext(next) + + if IsValid(next:GetNext()) then //we've come full circle. + + next.LastPoint = self:GetCurrentPoint() + + local id = select(2,zones.CreateZoneFromPoint(self:GetCurrentPoint())) + -- self:GetCurrentPoint():DeleteOnRemove(next) + self:SetCurrentPoint(NULL) + + local o = self.Owner + timer.Simple(.1,function() -- wait for it to sync. + if IsValid(o) then + o:SendLua("zones.ShowOptions("..id..")") + end + end) + + end + + end + end + + + end +end + +function SWEP:MergeZones() + + local tr = self.Owner:GetEyeTrace() + if tr.HitWorld then + self:SetCurrentPoint(NULL) + + elseif IsValid(tr.Entity) and tr.Entity:GetClass() == "ent_zone_point" then + + local curr = self:GetCurrentPoint() + local trent = tr.Entity + if not IsValid(curr) then + self:SetCurrentPoint(trent) + + else + //Merge the zones. + if curr:GetZoneID() != trent:GetZoneID() then + local cid = curr:GetZoneID() + + --Change the points. + for k,next in pairs(ents.FindByClass("ent_zone_point")) do + if next:GetZoneID() == cid then + + next:SetZoneID(trent:GetZoneID()) + next:SetAreaNumber(next:GetAreaNumber() + #zones.List[trent:GetZoneID()].points) + next:SetZoneClass(zones.List[trent:GetZoneID()].class) + + end + + end + + self:SetCurrentPoint(NULL) + + zones.Merge(cid,trent:GetZoneID()) --from, to + + else + self:SetCurrentPoint(trent) + + end + + end + + end +end + +function SWEP:UpdateSettings() + --load convars + local new_tall = SERVER and self.Owner:GetInfoNum("zone_tall",200) or GetConVarNumber("zone_tall") + local new_class = SERVER and self.Owner:GetInfo("zone_class") or GetConVarString("zone_class") + local new_mode = SERVER and self.Owner:GetInfoNum("zone_editmode",1) or GetConVarNumber("zone_editmode") + + if new_class == "" then + for k,v in pairs(zones.Classes)do + new_class = k + self.Owner:ConCommand('zone_class "'..k..'"') + break + end + end + + --If changed, remove current building area + if new_class != self:GetZoneClass() or new_tall != self:GetTall() or new_mode != self:GetMode() then + self:ResetTool() + end + assert(new_class != "", "No class is set for the zone designator! Did you call zones.RegisterClass()?\n") + + --apply convars + self:SetTall(new_tall) + self:SetZoneClass(new_class) + self:SetMode(new_mode) +end + +function SWEP:ResetTool() + + if self:GetMode() == 1 and SERVER then + local cur = self:GetCurrentPoint() + if IsValid(cur) and cur:GetZoneID() == -1 then + + while IsValid(cur) do + local last = cur.LastPoint + cur:Remove() + cur = last + end + + end + + end + self:SetCurrentPoint(NULL) +end + +function SWEP:OpenMenu() + local zc = self:GetZoneClass() + + local frame = vgui.Create("DFrame") + self.frame = frame + frame:SetSize(300,400) + frame:Center() + frame:MakePopup() + frame:ShowCloseButton(false) + frame:SetTitle("Zone Designator Options") + function frame:Think() + if not input.IsButtonDown(_G["KEY_"..input.LookupBinding("+reload"):upper()]) then + mx,my = gui.MousePos() + self:Close() + end + end + + local ztitle = vgui.Create("DLabel",frame) + ztitle:Dock(TOP) + ztitle:DockMargin(7,0,5,0) + ztitle:SetText("Zone Class:") + ztitle:SizeToContents() + + local zclass = vgui.Create("DComboBox",frame) + zclass:Dock(TOP) + zclass:DockMargin(5,0,5,0) + for k,v in pairs(zones.Classes) do + zclass:AddChoice(k,nil,k==zc) + end + function zclass:OnSelect(i,class) + RunConsoleCommand("zone_class",class) + end + + local filter = vgui.Create("DCheckBoxLabel",frame) + filter:Dock(TOP) + filter:DockMargin(6,5,5,5) + filter:SetText("Filter zones of a different class.") + filter:SizeToContents() + filter:SetConVar("zone_filter") + + local height = vgui.Create( "DNumSlider", frame ) + height:Dock(TOP) + height:DockMargin(7,0,0,0) + height:SetText( "Zone Height:" ) + height:SetMin( 0 ) + height:SetMax( 1000 ) + height:SetDecimals( 0 ) + height:SetConVar( "zone_tall" ) + + local modetitle = vgui.Create("DLabel",frame) + modetitle:Dock(TOP) + modetitle:DockMargin(7,0,5,0) + modetitle:SetText("Tool Mode:") + modetitle:SizeToContents() + + local mode = vgui.Create("DListView",frame) + mode:Dock(TOP) + mode:DockMargin(5,0,5,5) + mode:AddColumn("Mode") + mode:AddColumn("Info"):SetFixedWidth(180) + mode:SetTall(200) + mode:SetMultiSelect(false) + + mode:AddLine("Create / Delete","Create new zones") + mode:AddLine("Merge / Split","Turn two zones into one.") + mode:AddLine("Edit / Resize","Change zone properties.") + mode:AddLine("Insert / Remove","Insert points into existing zones.") + mode:SelectItem(mode:GetLine(self:GetMode())) + function mode:OnRowSelected(id) + RunConsoleCommand("zone_editmode",id) + end + + + local save = vgui.Create("DButton",frame) + save:Dock(BOTTOM) + save:DockMargin(5,0,5,5) + save:SetText("SAVE ALL ZONES") + save:SetFont("zones_save") + save:SetTextColor(color_black) + save:SetTall(50) + function save:DoClick() + Derma_Query("Are you sure you want to save? This can't be undone.", "Save Confirmation", + "Yes", function() + RunConsoleCommand("zone_save") + end, + "No", function() + end + ) + end + + + +end + +local modes = { + { --create + "Create", + "Delete" + }, + { --merge + "Merge", + "Split" + }, + { --edit + "Edit", + "Resize" + }, + { --insert + "Insert", + "Remove" + }, +} +local lmb, rmb = Material("gui/lmb.png","unlitgeneric"), Material("gui/rmb.png","unlitgeneric") +function SWEP:DrawScreen(x,y,w,h) + local mode = self:GetMode() + local txt = modes[mode] + + draw.SimpleText(txt[1], "zones_screen", x+w/4, -h/5, _, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) + draw.SimpleText(txt[2], "zones_screen", w+x-w/4, -h/5, _, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) + + surface.SetDrawColor(color_white) + surface.DrawRect(x+w/2-1,y+h*.125,2,h*.75) + + surface.SetMaterial(lmb) + surface.DrawTexturedRect(x+w/4-16,y+h*.55-16,32,32) + surface.SetMaterial(rmb) + surface.DrawTexturedRect(x+w*.75-16,y+h*.55-16,32,32) + +end + +local function GetBoneOrientation(self,ent) + local bone, pos, ang + bone = ent:LookupBone("Hand") + if (!bone) then return end + pos, ang = Vector(0,0,0), Angle(0,0,0) + local m = ent:GetBoneMatrix(bone) + if (m) then + pos, ang = m:GetTranslation(), m:GetAngles() + end + if (IsValid(self.Owner) and self.Owner:IsPlayer() and + ent == self.Owner:GetViewModel() and self.ViewModelFlip) then + ang.r = -ang.r // Fixes mirrored models + end + return pos, ang +end +function SWEP:ViewModelDrawn() + local vm = self.Owner:GetViewModel() + if !IsValid(vm) then return end + + local pos, ang = GetBoneOrientation(self, vm ) + local offset = Vector(.08, -5.16, 3.43) + local offsetAng = Angle(180, 0, -46) + local size = 0.0159 + local drawpos = pos + ang:Forward() * offset.x + ang:Right() * offset.y + ang:Up() * offset.z + ang:RotateAroundAxis(ang:Up(), offsetAng.y) + ang:RotateAroundAxis(ang:Right(), offsetAng.p) + ang:RotateAroundAxis(ang:Forward(), offsetAng.r) + + cam.Start3D2D(drawpos, ang, size) + local x,y,w,h = -72,-72 + local w,h = 2*-x, 2*-y + //Draw Background: + surface.SetDrawColor( 200, 200, 200, 255 ) + surface.SetDrawColor( 40,40,40,255 ) + surface.DrawRect( x, y, w, h ) + + //Draw foreground: + self:DrawScreen(x,y,w,h) + + cam.End3D2D() +end
\ No newline at end of file |
