add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,270 @@
--[[
3D2D VGUI Wrapper
Copyright (c) 2015-2017 Alexander Overvoorde, Matt Stevens
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]--
if SERVER then return end
local origin = Vector(0, 0, 0)
local angle = Angle(0, 0, 0)
local normal = Vector(0, 0, 0)
local scale = 0
local maxrange = 0
-- Helper functions
local function getCursorPos()
local p = util.IntersectRayWithPlane(LocalPlayer():EyePos(), LocalPlayer():GetAimVector(), origin, normal)
-- if there wasn't an intersection, don't calculate anything.
if not p then return end
if WorldToLocal(LocalPlayer():GetShootPos(), Angle(0,0,0), origin, angle).z < 0 then return end
if maxrange > 0 then
if p:Distance(LocalPlayer():EyePos()) > maxrange then
return
end
end
local pos = WorldToLocal(p, Angle(0,0,0), origin, angle)
return pos.x, -pos.y
end
local function getParents(pnl)
local parents = {}
local parent = pnl:GetParent()
while parent do
table.insert(parents, parent)
parent = parent:GetParent()
end
return parents
end
local function absolutePanelPos(pnl)
local x, y = pnl:GetPos()
local parents = getParents(pnl)
for _, parent in ipairs(parents) do
local px, py = parent:GetPos()
x = x + px
y = y + py
end
return x, y
end
local function pointInsidePanel(pnl, x, y)
local px, py = absolutePanelPos(pnl)
local sx, sy = pnl:GetSize()
if not x or not y then return end
x = x / scale
y = y / scale
return x >= px and y >= py and x <= px + sx and y <= py + sy --pnl:IsVisible() and x >= px and y >= py and x <= px + sx and y <= py + sy
end
-- Input
local inputWindows = {}
local usedpanel = {}
local function isMouseOver(pnl)
return pointInsidePanel(pnl, getCursorPos())
end
local function postPanelEvent(pnl, event, ...)
if not IsValid(pnl) or not pointInsidePanel(pnl, getCursorPos()) then return false end -- not pnl:IsVisible() or not pointInsidePanel(pnl, getCursorPos()) then return false end
local handled = false
for i, child in pairs(table.Reverse(pnl:GetChildren())) do
if postPanelEvent(child, event, ...) then
handled = true
break
end
end
if not handled and pnl[event] then
pnl[event](pnl, ...)
usedpanel[pnl] = {...}
return true
else
return false
end
end
-- Always have issue, but less
local function checkHover(pnl, x, y, found)
if not (x and y) then
x, y = getCursorPos()
end
local validchild = false
for c, child in pairs(table.Reverse(pnl:GetChildren())) do
local check = checkHover(child, x, y, found or validchild)
if check then
validchild = true
end
end
if found then
if pnl.Hovered then
pnl.Hovered = false
if pnl.OnCursorExited then pnl:OnCursorExited() end
end
else
if not validchild and pointInsidePanel(pnl, x, y) then
pnl.Hovered = true
if pnl.OnCursorEntered then pnl:OnCursorEntered() end
return true
else
pnl.Hovered = false
if pnl.OnCursorExited then pnl:OnCursorExited() end
end
end
return false
end
-- Mouse input
hook.Add("KeyPress", "VGUI3D2DMousePress", function(_, key)
if key == IN_USE then
for pnl in pairs(inputWindows) do
if IsValid(pnl) then
origin = pnl.Origin
scale = pnl.Scale
angle = pnl.Angle
normal = pnl.Normal
local key = input.IsKeyDown(KEY_LSHIFT) and MOUSE_RIGHT or MOUSE_LEFT
postPanelEvent(pnl, "OnMousePressed", key)
end
end
end
end)
hook.Add("KeyRelease", "VGUI3D2DMouseRelease", function(_, key)
if key == IN_USE then
for pnl, key in pairs(usedpanel) do
if IsValid(pnl) then
origin = pnl.Origin
scale = pnl.Scale
angle = pnl.Angle
normal = pnl.Normal
if pnl["OnMouseReleased"] then
pnl["OnMouseReleased"](pnl, key[1])
end
usedpanel[pnl] = nil
end
end
end
end)
function vgui.Start3D2D(pos, ang, res)
origin = pos
scale = res
angle = ang
normal = ang:Up()
maxrange = 0
cam.Start3D2D(pos, ang, res)
end
function vgui.MaxRange3D2D(range)
maxrange = isnumber(range) and range or 0
end
function vgui.IsPointingPanel(pnl)
origin = pnl.Origin
scale = pnl.Scale
angle = pnl.Angle
normal = pnl.Normal
return pointInsidePanel(pnl, getCursorPos())
end
local Panel = FindMetaTable("Panel")
function Panel:Paint3D2D()
if not self:IsValid() then return end
-- Add it to the list of windows to receive input
inputWindows[self] = true
-- Override gui.MouseX and gui.MouseY for certain stuff
local oldMouseX = gui.MouseX
local oldMouseY = gui.MouseY
local cx, cy = getCursorPos()
function gui.MouseX()
return (cx or 0) / scale
end
function gui.MouseY()
return (cy or 0) / scale
end
-- Override think of DFrame's to correct the mouse pos by changing the active orientation
if self.Think then
if not self.OThink then
self.OThink = self.Think
self.Think = function()
origin = self.Origin
scale = self.Scale
angle = self.Angle
normal = self.Normal
self:OThink()
end
end
end
-- Update the hover state of controls
local _, tab = checkHover(self)
-- Store the orientation of the window to calculate the position outside the render loop
self.Origin = origin
self.Scale = scale
self.Angle = angle
self.Normal = normal
-- Draw it manually
self:SetPaintedManually(false)
self:PaintManual()
self:SetPaintedManually(true)
gui.MouseX = oldMouseX
gui.MouseY = oldMouseY
end
function vgui.End3D2D()
cam.End3D2D()
end

View File

@@ -0,0 +1,44 @@
local tabPoisonEffect = {
[ "$pp_colour_addr" ] = 0.3,
[ "$pp_colour_addg" ] = 0.3,
[ "$pp_colour_addb" ] = 0,
[ "$pp_colour_brightness" ] = 0,
[ "$pp_colour_contrast" ] = 1,
[ "$pp_colour_colour" ] = 0.8,
[ "$pp_colour_mulr" ] = 0,
[ "$pp_colour_mulg" ] = 0,
[ "$pp_colour_mulb" ] = 0
}
local tabBleedingEffect = {
[ "$pp_colour_addr" ] = 0.0,
[ "$pp_colour_addg" ] = 0.0,
[ "$pp_colour_addb" ] = 0.0,
[ "$pp_colour_brightness" ] = 0,
[ "$pp_colour_contrast" ] = 1,
[ "$pp_colour_colour" ] = 1,
[ "$pp_colour_mulr" ] = 0,
[ "$pp_colour_mulg" ] = 0,
[ "$pp_colour_mulb" ] = 0
}
function MedicMod.BleedingEffect()
if LocalPlayer():IsMorphine() then return end
tabBleedingEffect[ "$pp_colour_addr" ] = math.abs(math.sin( CurTime() * 2 )) * 0.2
DrawColorModify( tabBleedingEffect )
end
function MedicMod.PoisonEffect()
if LocalPlayer():IsMorphine() then return end
DrawColorModify( tabPoisonEffect )
DrawMotionBlur( 0.1, 0.7, 0.05 )
end

View File

@@ -0,0 +1,158 @@
surface.CreateFont( "MedicModFont100", {
font = "Arial",
size = 100,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "MedicModFont30", {
font = "Arial",
size = 30,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "MedicModFont20", {
font = "Arial",
size = 20,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "MedicModFont17", {
font = "Arial",
size = 17,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "MedicModFont15", {
font = "Arial",
size = 15,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "MedicModFont12", {
font = "Arial",
size = 12,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "MedicModFont10", {
font = "Arial",
size = 10,
weight = 600,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
});
surface.CreateFont( "WrittenMedicMod80", {
font = "Written on His Hands",
size = 80,
weight = 1000
} )
surface.CreateFont( "WrittenMedicMod40", {
font = "Written on His Hands",
size = 40,
weight = 1000
} )
surface.CreateFont( "WrittenMedicMod35", {
font = "Written on His Hands",
size = 35,
weight = 1000
} )
surface.CreateFont("Aam::Title", {
font = "Trebuchet24",
size = 36,
weight = 350
})
surface.CreateFont("Aam::Button", {
font = "Trebuchet24",
size = 24,
weight = 350
})
surface.CreateFont("Aam::Normal", {
font = "Trebuchet24",
size = 24,
weight = 300
})

View File

@@ -0,0 +1,255 @@
local meta = FindMetaTable( "Player" )
local sentences = ConfigurationMedicMod.Sentences
local lang = ConfigurationMedicMod.Language
function StartMedicAnimation( ply, id )
if not IsValid(ply) then return end
if ply.mdlanim && IsValid( ply.mdlanim ) then print("model already exist, removed") ply.mdlanim:Remove() end
if ply:GetNWString("MedicPlayerModel") then
ply.mdlanim = ClientsideModel(ply:GetNWString("MedicPlayerModel"))
if IsValid( ply.mdlanim ) then
ply.mdlanim:SetParent( ply )
ply.mdlanim:AddEffects( EF_BONEMERGE )
return ply.mdlanim
else
return false
end
end
end
function StopMedicAnimation( ply )
if IsValid( ply.mdlanim ) && ply:GetMedicAnimation() == 0 then
ply.mdlanim:Remove()
end
end
local Background = Material( "medic/terminal/background.png" )
local ArrowRight = Material( "medic/terminal/arrow_right.png" )
local ArrowLeft = Material( "medic/terminal/arrow_left.png" )
function MedicMod.TerminalMenu( ent )
local ActiveItem = 1
/* MAIN FRAME */
local _MainFrame = vgui.Create( "DPanel" )
_MainFrame:SetSize( 750, 500 )
_MainFrame:Center()
_MainFrame:MakePopup()
_MainFrame.Paint = function( pnl, w, h )
/* BACKGROUND */
surface.SetDrawColor( 255, 255, 255 )
surface.SetMaterial( Background )
surface.DrawTexturedRect( 0, 0, w, h )
draw.RoundedBox( 0, 0, 0, w, h, Color( 0, 0, 0, 225 ))
/* TOP */
draw.RoundedBox( 0, 0, 0, w, h*0.2, Color( 255, 255, 255, 10 ))
draw.DrawText( "Terminal", "MedicModFont17", w*0.5, h*0.065, Color( 255, 255, 255 ), 1)
/* BOTTOM */
draw.DrawText( ConfigurationMedicMod.Entities[ActiveItem].price..ConfigurationMedicMod.MoneyUnit, "Aam::Normal", w*0.5, h*0.785, Color( 255, 255, 255 ), 1)
draw.RoundedBox( 0, w*0.2, h*0.75, w*0.6, 2, Color( 255, 255, 255 ))
end
/* SCROLL SYSTEM */
local ItemScrollPanel = vgui.Create("DScrollPanel", _MainFrame )
ItemScrollPanel:SetSize( _MainFrame:GetWide()*0.6, _MainFrame:GetTall()*0.45 )
ItemScrollPanel:SetPos( _MainFrame:GetWide()*0.2, _MainFrame:GetTall()*0.25 )
ItemScrollPanel:GetVBar().Paint = function()
end
ItemScrollPanel:GetVBar().btnGrip.Paint = function()
end
ItemScrollPanel:GetVBar().btnUp.Paint = function()
end
ItemScrollPanel:GetVBar().btnDown.Paint = function()
end
/* ITEM LIST */
local ItemsList = vgui.Create( "DIconLayout", ItemScrollPanel )
ItemsList:SetSize( ItemScrollPanel:GetWide(), ItemScrollPanel:GetTall() )
ItemsList:SetPos( 0, 0 )
ItemsList:SetSpaceY( 0 )
ItemsList:SetSpaceX( 0 )
ItemSlot = {}
for k, v in pairs( ConfigurationMedicMod.Entities ) do
ItemSlot[k] = vgui.Create( "DPanel", ItemsList )
ItemSlot[k]:SetSize( ItemsList:GetWide(), ItemsList:GetTall() )
ItemSlot[k].Paint = function( pnl, w, h )
draw.DrawText( v.name, "MedicModFont17", w*0.5, h*0.1, Color( 255, 255, 255 ), 1)
end
ItemSlot[k].model = vgui.Create( "DModelPanel", ItemSlot[k] )
ItemSlot[k].model:SetPos( 0, 100 )
ItemSlot[k].model:SetSize( ItemsList:GetWide(), ItemsList:GetTall()-100 )
ItemSlot[k].model:SetLookAt( Vector(0, 0, 0 ) )
ItemSlot[k].model:SetCamPos( Vector( -50, 0, 30 ) )
ItemSlot[k].model:SetModel( v.mdl )
end
/* LEFT */
local _LeftArrow = vgui.Create( "DButton", _MainFrame )
_LeftArrow:SetSize( 50, 50 )
_LeftArrow:SetPos( _MainFrame:GetWide()*0.1, _MainFrame:GetTall()*0.4 )
_LeftArrow:SetText("")
_LeftArrow.Paint = function( pnl, w, h )
surface.SetDrawColor( 255, 255, 255 )
surface.SetMaterial( ArrowLeft )
surface.DrawTexturedRect( 0, 0, w, h )
end
_LeftArrow.DoClick = function()
if ActiveItem == 1 then return end
ActiveItem = ActiveItem - 1
ItemScrollPanel:ScrollToChild(ItemSlot[ActiveItem])
end
/* RIGHT */
local _RightArrow = vgui.Create( "DButton", _MainFrame )
_RightArrow:SetSize( 50, 50 )
_RightArrow:SetPos( _MainFrame:GetWide()*0.9 - 50, _MainFrame:GetTall()*0.4 )
_RightArrow:SetText("")
_RightArrow.Paint = function( pnl, w, h )
surface.SetDrawColor( 255, 255, 255 )
surface.SetMaterial( ArrowRight )
surface.DrawTexturedRect( 0, 0, w, h )
end
_RightArrow.DoClick = function()
if ActiveItem == table.Count( ConfigurationMedicMod.Entities ) then return end
ActiveItem = ActiveItem + 1
ItemScrollPanel:ScrollToChild(ItemSlot[ActiveItem])
end
/* BUY */
local _BuyButton = vgui.Create( "DButton", _MainFrame )
_BuyButton:SetSize( _MainFrame:GetWide()*0.15, _MainFrame:GetTall()*0.0725 )
_BuyButton:SetPos( _MainFrame:GetWide()*0.5 - ( _BuyButton:GetWide() / 2 ), _MainFrame:GetTall()*0.9 )
_BuyButton:SetText("")
_BuyButton.Color = Color(200,200,200,255)
_BuyButton.Paint = function( pnl, w, h )
local color = _BuyButton.Color
draw.DrawText( sentences["Buy"][lang], "Aam::Button", w*0.5, h*0.1, color, 1)
if _BuyButton:IsHovered() then
local r = math.Clamp(color.r+10, 200, 255 )
local g = math.Clamp(color.g+10, 200, 255 )
local b = math.Clamp(color.b+10, 200, 255 )
_BuyButton.Color = Color(r,g,b,255)
else
local r = math.Clamp(color.r-5, 200, 255 )
local g = math.Clamp(color.g-5, 200, 255 )
local b = math.Clamp(color.b-5, 200, 255 )
_BuyButton.Color = Color(r,g,b,255)
end
draw.RoundedBox( 3, 0, 0, w, 2, color)
draw.RoundedBox( 3, 0, 0, 2, h, color)
draw.RoundedBox( 3, 0, h-2, w, 2, color)
draw.RoundedBox( 3, w-2, 0, 2, h, color)
end
_BuyButton.DoClick = function()
net.Start("MedicMod.BuyMedicEntity")
net.WriteInt( ActiveItem, 32 )
net.WriteEntity( ent )
net.SendToServer()
_MainFrame:Remove()
end
/* CLOSE BUTTON */
local _CloseButton = vgui.Create( "DButton", _MainFrame )
_CloseButton:SetSize( _MainFrame:GetWide()*0.05, _MainFrame:GetTall()*0.0725 )
_CloseButton:SetPos( _MainFrame:GetWide()*0.99 - ( _CloseButton:GetWide() ), _MainFrame:GetTall()*0.01 )
_CloseButton:SetText("")
_CloseButton.Color = Color(200,200,200,255)
_CloseButton.Paint = function( pnl, w, h )
local color = _CloseButton.Color
draw.DrawText( "X", "Aam::Button", w*0.5, h*0.1, color, 1)
if _CloseButton:IsHovered() then
local r = math.Clamp(color.r+10, 200, 255 )
local g = math.Clamp(color.g+10, 200, 255 )
local b = math.Clamp(color.b+10, 200, 255 )
_CloseButton.Color = Color(r,g,b,255)
else
local r = math.Clamp(color.r-5, 200, 255 )
local g = math.Clamp(color.g-5, 200, 255 )
local b = math.Clamp(color.b-5, 200, 255 )
_CloseButton.Color = Color(r,g,b,255)
end
draw.RoundedBox( 3, 0, 0, w, 2, color)
draw.RoundedBox( 3, 0, 0, 2, h, color)
draw.RoundedBox( 3, 0, h-2, w, 2, color)
draw.RoundedBox( 3, w-2, 0, 2, h, color)
end
_CloseButton.DoClick = function()
_MainFrame:Remove()
end
end

View File

@@ -0,0 +1,123 @@
hook.Add( "CalcView", "CalcView.MedicMod", function( ply, pos, ang, fov )
if ( !IsValid( ply ) or !ply:Alive() or ply:GetViewEntity() != ply ) then return end
if ply:GetMedicAnimation() != 0 then
local view = {}
view.origin = pos - ( ang:Forward()*20 )
view.angles = ang
view.fov = fov
view.drawviewer = true
return view
end
--[[
if ply:GetNWBool("CarryingRagdoll", false) then
local view = {}
local tilted = Angle(ang.p, ang.y, ang.r)
tilted:RotateAroundAxis(ang:Forward(), 18)
view.origin = pos
view.angles = tilted
view.fov = fov
view.drawviewer = false
return view
end
]]
end)
hook.Add("RenderScreenspaceEffects", "RenderScreenspaceEffects.MedicMod", function()
if LocalPlayer():IsBleeding() then
MedicMod.BleedingEffect()
end
if LocalPlayer():IsPoisoned() then
MedicMod.PoisonEffect()
end
end)
local bleedingIcon = Material("materials/bleeding.png")
local poisonedIcon = Material("materials/poisoned.png")
local hattackIcon = Material("materials/heart_attack_icon.png")
local morphIcon = Material("materials/morphine_icon.png")
local breakIcon = Material("materials/break_icon.png")
local notifIcon = Material("materials/heart_attack_icon.png")
local deathPanel = nil
hook.Add("HUDPaint", "HUDPaint.MedicMod", function()
if ConfigurationMedicMod.MedicTeams and table.HasValue(ConfigurationMedicMod.MedicTeams, LocalPlayer():Team()) then
for k, v in pairs(ents.FindByClass("prop_ragdoll")) do
if not v:IsDeathRagdoll() then continue end
local pos = ( v:GetPos() + Vector(0,0,10) ):ToScreen()
local dist = v:GetPos():Distance(LocalPlayer():GetPos())
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( notifIcon )
surface.DrawTexturedRect( pos.x - 25, pos.y, 50, 50 )
draw.SimpleTextOutlined( math.floor(math.sqrt(dist/3)).."m", "MedicModFont30", pos.x, pos.y + 50, Color( 255, 255, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, Color( 0, 0, 0, 255 ) )
end
end
--[[
local carryText = nil
if LocalPlayer():GetNWBool("CarryingRagdoll", false) then
carryText = ConfigurationMedicMod.Sentences["You dropped the corpse"][ConfigurationMedicMod.Language]
else
local trace = LocalPlayer():GetEyeTraceNoCursor()
if IsValid(trace.Entity) and trace.Entity:IsDeathRagdoll() and not trace.Entity:GetNWBool("IsRagdollCarried", false) and trace.HitPos:Distance(LocalPlayer():GetPos()) <= 120 then
carryText = ConfigurationMedicMod.Sentences["Press E to carry corpse"][ConfigurationMedicMod.Language]
end
end
if carryText then
draw.SimpleTextOutlined(carryText, "MedicModFont30", ScrW() / 2, ScrH() - 80, Color(255, 255, 0, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 2, Color(0, 0, 0, 255))
end
]]
local nbStat = 1
if LocalPlayer():IsBleeding() then
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( bleedingIcon )
surface.DrawTexturedRect( ScrW() - 300, ScrH() - 150 - 50 * nbStat, 50, 50 )
draw.SimpleTextOutlined( ConfigurationMedicMod.Sentences["Bleeding"][ConfigurationMedicMod.Language], "MedicModFont30", ScrW() - 240, ScrH() - 140 - 50 * nbStat, Color( 255, 0, 0, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, Color( 0, 0, 0, 255 ) )
nbStat = nbStat + 1
end
if LocalPlayer():IsPoisoned() then
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( poisonedIcon )
surface.DrawTexturedRect( ScrW() - 300, ScrH() - 150 - 50 * nbStat, 50, 50 )
draw.SimpleTextOutlined( ConfigurationMedicMod.Sentences["Poisoned"][ConfigurationMedicMod.Language], "MedicModFont30", ScrW() - 240, ScrH() - 140 - 50 * nbStat, Color( 153, 201, 158, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, Color( 0, 0, 0, 255 ) )
nbStat = nbStat + 1
end
if LocalPlayer():GetHeartAttack() then
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( hattackIcon )
surface.DrawTexturedRect( ScrW() - 300, ScrH() - 150 - 50 * nbStat, 50, 50 )
draw.SimpleTextOutlined( ConfigurationMedicMod.Sentences["Heart Attack"][ConfigurationMedicMod.Language], "MedicModFont30", ScrW() - 240, ScrH() - 140 - 50 * nbStat , Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, Color( 0, 0, 0, 255 ) )
nbStat = nbStat + 1
end
if LocalPlayer():IsMorphine() then
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( morphIcon )
surface.DrawTexturedRect( ScrW() - 300, ScrH() - 150 - 50 * nbStat, 50, 50 )
draw.SimpleTextOutlined( ConfigurationMedicMod.Sentences["Morphine"][ConfigurationMedicMod.Language], "MedicModFont30", ScrW() - 240, ScrH() - 140 - 50 * nbStat, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, Color( 0, 0, 0, 255 ) )
nbStat = nbStat + 1
end
if LocalPlayer():IsFractured() then
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( breakIcon )
surface.DrawTexturedRect( ScrW() - 300, ScrH() - 150 - 50 * nbStat, 50, 50 )
draw.SimpleTextOutlined( ConfigurationMedicMod.Sentences["Fracture"][ConfigurationMedicMod.Language], "MedicModFont30", ScrW() - 240, ScrH() - 140 - 50 * nbStat, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, Color( 0, 0, 0, 255 ) )
nbStat = nbStat + 1
end
end)

View File

@@ -0,0 +1,858 @@
local sentences = ConfigurationMedicMod.Sentences
local lang = ConfigurationMedicMod.Language
local function CreateCloseButton( Parent, Panel, color, sx, sy, back, backcolor)
Parent = Parent or ""
sx = sx or 50
sy = sy or 20
color = color or Color(255,255,255,255)
back = back or false
backcolor = backcolor or false
local x,y = Parent:GetSize()
local CloseButton = vgui.Create("DButton", Parent)
CloseButton:SetPos(x-sx, 0)
CloseButton:SetSize(sx,sy)
CloseButton:SetFont("Trebuchet24")
CloseButton:SetTextColor( color )
CloseButton:SetText("X")
function CloseButton:DoClick()
Panel:Close()
end
CloseButton.Paint = function(s , w , h)
if back then
draw.RoundedBox(0,0,0,w , h,backcolor)
end
end
return CloseButton
end
local function CreateButton( Parent, text, font, colorText, px, py, sx, sy, func, back, backcolor, backcolorbar, sound)
Parent = Parent or ""
font = font or "Trebuchet18"
text = text or ""
px = px or 0
py = py or 0
sx = sx or 50
sound = sound or true
func = func or function() end
sy = sy or 50
colorText = colorText or Color(255,255,255,255)
back = back or true
backcolor = backcolor or Color( 0, 100 , 150 )
backcolorbar = backcolorbar or Color( 0 , 80 , 120 )
local Button = vgui.Create("DButton", Parent)
Button:SetPos( px , py )
Button:SetSize(sx,sy)
Button:SetFont("Trebuchet24")
Button:SetTextColor( colorText )
Button:SetText(text)
function Button:DoClick()
func()
if sound then
surface.PlaySound( "UI/buttonclick.wav" )
end
end
if sound then
function Button:OnCursorEntered()
surface.PlaySound( "UI/buttonrollover.wav" )
end
end
Button.Paint = function(s , w , h)
if back then
if Button:IsHovered() then
draw.RoundedBox(0,0,0,w , h, Color( backcolor.r + 30, backcolor.g + 30, backcolor.b + 30 ))
draw.RoundedBox(0,0,h-sy/10,sx , sy/10, Color( backcolorbar.r + 30, backcolorbar.g + 30, backcolorbar.b + 30 ))
else
draw.RoundedBox(0,0,0,w , h, backcolor)
draw.RoundedBox(0,0,h-sy/10,sx , sy/10, backcolorbar)
end
end
end
return Button
end
local function CreatePanel( Parent, sx, sy, posx, posy, backcolor, scroll, bar, grip, btn)
Parent = Parent or ""
sx = sx or 100
sy = sy or 100
backcolor = backcolor or Color(35, 35, 35, 255)
posx = posx or 0
posy = posy or 0
scroll = scroll or false
bar = bar or Color( 30, 30, 30 )
grip = grip or Color( 0, 140, 208 )
btn = btn or Color( 4,95,164 )
local typ = "DPanel"
if scroll then
typ = "DScrollPanel"
else
typ = "DPanel"
end
local Panel = vgui.Create(typ, Parent)
Panel:SetSize(sx,sy)
Panel:SetPos(posx,posy)
Panel.Paint = function(s , w , h)
draw.RoundedBox(0,0,0,w , h, backcolor)
end
if typ == "DScrollPanel" then
local sbar = Panel:GetVBar()
function sbar:Paint( w, h )
draw.RoundedBox( 0, 0, 0, w, h, bar )
end
function sbar.btnUp:Paint( w, h )
draw.SimpleText( "?", "Trebuchet24", -3, -4, btn )
end
function sbar.btnDown:Paint( w, h )
draw.SimpleText( "?", "Trebuchet24", -3, -4, btn )
end
function sbar.btnGrip:Paint( w, h )
draw.RoundedBox( 8, 0, 0, w, h, grip )
end
end
return Panel
end
local function CreateLabel( Parent, font, text, sx, sy, posx, posy, color, time)
Parent = Parent or ""
font = font or "Trebuchet24"
text = text or ""
sx = sx or 100
sy = sy or 100
posx = posx or 0
posy = posy or 0
color = color or Color(255,255,255,255)
time = time or 0
local EndTime = CurTime() + time
local SizeString = string.len( text )
local Label = vgui.Create("DLabel", Parent)
Label:SetPos( posx, posy )
Label:SetSize( sx,sy )
if time == 0 then
Label:SetText( text )
else
Label:SetText( "" )
end
Label:SetWrap( true )
Label:SetTextColor(color)
Label:SetFont(font)
Label.Think = function()
if Label:GetText() == text then
return
end
local TimeLeft = EndTime - CurTime()
local StringSizeP1 = ( TimeLeft / ( time / 100 ) ) / 100
local StringSize = 1 - StringSizeP1
Label:SetText( string.sub(text, 0, SizeString * StringSize ))
end
return Label
end
local SizeX = 400
local SizeY = 250
net.Receive("MedicMod.MedicMenu", function()
local ent = net.ReadEntity()
local fract = net.ReadTable()
local FramePrincipal = vgui.Create( "DFrame" )
FramePrincipal:SetSize( SizeX, SizeY )
FramePrincipal:SetPos( ScrW()/2 - SizeX/2, ScrH()/2 - SizeY/2 )
FramePrincipal:SetTitle( "Panel" )
FramePrincipal:SetDraggable( false )
FramePrincipal:ShowCloseButton( false )
FramePrincipal:MakePopup()
FramePrincipal.Paint = function(s , w , h)
end
local boxTitle = CreatePanel( FramePrincipal, SizeX, 20, 0, 0, Color(0, 140, 208, 255), false )
local CloseButton = CreateCloseButton( boxTitle, FramePrincipal )
local LabelTitle = CreateLabel( boxTitle, "Trebuchet24", "Medecin", SizeX-40, 20, 50, 0, nil, 0)
local boxContent = CreatePanel( FramePrincipal, SizeX, SizeY-20, 0, 20, Color(35, 35, 35, 255), true )
local fractn = table.Count(fract)
if LocalPlayer():Health() < LocalPlayer():GetMaxHealth() or fractn > 0 then
local money = ( LocalPlayer():GetMaxHealth() - LocalPlayer():Health() ) * ConfigurationMedicMod.HealthUnitPrice
if fractn > 0 then
money = money + fractn * ConfigurationMedicMod.FractureRepairPrice
end
local Label1 = CreateLabel( boxContent, nil, sentences["Hello, you look sick. I can heal you, it will cost"][lang].." "..money..ConfigurationMedicMod.MoneyUnit.."." , SizeX - 40, SizeY - 35 - 50 - 10, 10, 0, nil, 3)
local Button1 = CreateButton( boxContent, sentences["Heal me"][lang], nil, nil, SizeX/2-75, SizeY - 50 - 10 - 25, 150, 50, function() net.Start("MedicMod.MedicStart") net.WriteEntity( ent ) net.SendToServer() FramePrincipal:Close() end )
else
local Label1 = CreateLabel( boxContent, nil, sentences["Hello, you seem healthy-looking today"][lang] , SizeX - 40, SizeY - 35 - 50 - 10, 10, 0, nil, 2)
local Button1 = CreateButton( boxContent, sentences["Thanks"][lang], nil, nil, SizeX/2-75, SizeY - 50 - 10 - 25, 150, 50, function() FramePrincipal:Close() end )
end
end)
-- net.Receive("MedicMod.NotifiyPlayer", function()
-- local msg = net.ReadString()
-- local time = net.ReadInt( 32 )
-- MedicNotif( msg, time )
-- end)
net.Receive("MedicMod.ScanRadio", function()
local ent = net.ReadEntity()
local fractures = net.ReadTable()
ent.fracturesTable = fractures
end)
net.Receive("MedicMod.PlayerStartAnimation", function()
timer.Simple(0.15, function()
for k, v in pairs(player.GetAll()) do
if not v:GetMedicAnimation() then continue end
if v:GetMedicAnimation() != 0 then
StartMedicAnimation( v, v:GetMedicAnimation() )
end
end
end)
end)
net.Receive("MedicMod.PlayerStopAnimation", function()
timer.Simple(0.15, function()
for k, v in pairs(player.GetAll()) do
if v:GetMedicAnimation() == 0 and IsValid( v.mdlanim ) then
StopMedicAnimation( v )
end
end
end)
end)
net.Receive("MedicMod.Respawn", function()
MedicMod.seconds = net.ReadInt(32)
end)
net.Receive("MedicMod.TerminalMenu", function()
local ent = net.ReadEntity()
if not IsValid( ent ) then return end
MedicMod.TerminalMenu( ent )
end)
-- medic menu
for i=1,30 do
surface.CreateFont( "Bariol"..i, {
font = "Bariol Regular", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name
extended = false,
size = i,
weight = 750,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
} )
end
local venalib = {}
local matCloseButton = Material( "materials/medic/lib/close_button.png" )
venalib.Frame = function( sizex, sizey, posx, posy, parent )
local parent = parent or nil
local sizex = sizex or 500
local sizey = sizey or 500
local frame = vgui.Create("DFrame", parent)
frame:SetSize( sizex, sizey )
frame:MakePopup()
frame:ShowCloseButton(false)
frame:SetTitle("")
if not posx or not posy then
frame:Center()
else
frame:SetPos( posx, posy )
end
frame.Paint = function( pnl, w, h )
draw.RoundedBox( 3, 0, 0, w,h, Color( 46, 46, 54))
draw.RoundedBox( 3, 0, 0, w,40, Color( 36, 36, 44))
draw.RoundedBox( 0, 0, 40, w,2, Color( 26, 26, 34))
draw.SimpleText( sentences["Medic"][lang].." - Menu", "Bariol20", 10, 10, Color( 255, 255, 255, 255 ) )
end
local DermaButton = vgui.Create( "DButton", frame )
DermaButton:SetText( "" )
DermaButton:SetPos( sizex-30, 15/2 )
DermaButton:SetSize( 25, 25 )
DermaButton.DoClick = function()
if frame then frame:Remove() end
end
DermaButton.Paint = function( pnl, w, h )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetMaterial( matCloseButton )
surface.DrawTexturedRect( 0, 0, 25, 25 )
end
local dpanel = vgui.Create("DPanel", frame)
dpanel:SetPos( 0, 42 )
dpanel:SetSize( sizex, sizey-42 )
dpanel.Paint = function( pnl, w, h )
end
return dpanel
end
venalib.Panel = function( sizex, sizey, posx, posy, parent )
local parent = parent or nil
local sizex = sizex or 500
local sizey = sizey or 500
local panel = vgui.Create("DScrollPanel", parent)
panel:SetSize( sizex, sizey )
if not posx or not posy then
panel:SetPos(0,0)
else
panel:SetPos( posx, posy )
end
panel.Paint = function( pnl, w, h )
draw.RoundedBox( 0, 0, 0, w,h, Color(36, 36, 44))
draw.RoundedBox( 0, 0, 0, w,h-2, Color(46, 46, 54))
end
local sbar = panel:GetVBar()
function sbar:Paint( w, h )
draw.RoundedBox( 0, 0, 0, w, h, Color(56, 56, 64) )
end
function sbar.btnUp:Paint( w, h )
draw.RoundedBox( 0, 0, 0, w, h, Color(36, 36, 44) )
end
function sbar.btnDown:Paint( w, h )
draw.RoundedBox( 0, 0, 0, w, h, Color(36, 36, 44) )
end
function sbar.btnGrip:Paint( w, h )
draw.RoundedBox( 0, 0, 0, w, h, Color(31, 31, 39) )
end
return panel
end
venalib.Label = function( text, font, sx, sy, posx, posy, color, Parent, time)
Parent = Parent or ""
font = font or 15
text = text or ""
sx = sx or 100
sy = sy or 100
posx = posx or 0
posy = posy or 0
color = color or Color(255,255,255,255)
time = time or 0
local EndTime = CurTime() + time
local SizeString = string.len( text )
local Label = vgui.Create("DLabel", Parent)
Label:SetPos( posx, posy )
Label:SetSize( sx,sy )
if time == 0 then
Label:SetText( text )
else
Label:SetText( "" )
end
Label:SetWrap( true )
Label:SetTextColor(color)
Label:SetFont("Bariol"..font)
Label.Think = function()
if Label:GetText() == text then
return
end
local TimeLeft = EndTime - CurTime()
local StringSizeP1 = ( TimeLeft / ( time / 100 ) ) / 100
local StringSize = 1 - StringSizeP1
Label:SetText( string.sub(text, 0, SizeString * StringSize ))
end
return Label
end
venalib.Button = function( text, sizex, sizey, posx, posy, func, parent )
local text = text or ""
local sizex = sizex or 100
local sizey = sizey or 30
local posx = posx or 0
local posy = posy or 0
local parent = parent or nil
local func = func or function() end
local button = vgui.Create( "DButton", parent )
button:SetText( "" )
button:SetPos( posx, posy)
button:SetSize( sizex, sizey )
local colorr = 36
local colorg = 36
local colorb = 44
function button:DoClick()
func()
surface.PlaySound( "UI/buttonclick.wav" )
end
button.Paint = function( pnl, w, h )
local color = Color( 36, 36, 44)
local pa = 0.1
if button:IsHovered() then
colorr = math.Clamp( colorr + pa, 36, 36+5 )
colorg = math.Clamp( colorg + pa, 36, 36+5 )
colorb = math.Clamp( colorb + pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
else
colorr = math.Clamp( colorr - pa, 36, 36+5 )
colorg = math.Clamp( colorg - pa, 36, 36+5 )
colorb = math.Clamp( colorb - pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
end
draw.RoundedBox( 0, 0, 0, w,h-2, color)
draw.RoundedBox( 0, 0, h-2, w,2, Color( 26, 26, 34))
-- draw.RoundedBox( 0, w-2, 0, 2,h, Color( 31, 31, 41))
draw.SimpleText( text, "Bariol17", 10, sizey/2-17/2-2, Color( 255, 255, 255, 255 ) )
end
function button:OnCursorEntered()
surface.PlaySound( "UI/buttonrollover.wav" )
end
return button
end
local sizex = 800
local sizey = 600
local function OpenTestTubesPart(MainFrame)
local sizex = 800
local sizey = 600
local panelM = venalib.Panel( sizex-160, sizey-40, 160, 0, MainFrame )
local nbing = 0
for k , v in pairs( ConfigurationMedicMod.Reagents ) do
local name = k
local price = v.price or 10
local x = (sizex-160-40-10)/2
local y = 100
local ispair = math.mod( nbing, 2 )
local panelMIng = venalib.Panel( x, y, 10+(10+(x))*ispair, 10 + math.floor(nbing/2) * (y+10), panelM )
panelMIng.Paint = function( pnl, w, h )
draw.RoundedBox( 0, 0, 0, w,h, Color(36, 36, 44))
end
local icon = vgui.Create( "SpawnIcon", panelMIng )
icon:SetPos( 10, 10 )
icon:SetSize( 80, 80 )
icon:SetModel( "models/medicmod/test_tube/testtube.mdl" )
function icon:LayoutEntity( Entity ) return end
local text = venalib.Label( sentences["Test tube"][lang]..": "..name, 14, x-100-20, 30, 110, 10, Color(255,255,255), panelMIng)
text:SetWrap(false)
local text2 = venalib.Label( price..ConfigurationMedicMod.MoneyUnit, 14, x-100-20, 70, 110, 10, Color(255,255,255), panelMIng)
text2:SetWrap(false)
local button1 = venalib.Button( "> "..sentences["Buy"][lang], x-100-20, 40, x-(x-100-20)-10, y - 45 , function()
net.Start("MedicMod.BuyMedicJobEntity")
net.WriteString( k )
net.WriteString( "test_tube_medicmod_s" )
net.SendToServer()
end,panelMIng )
local colorr = 36
local colorg = 36
local colorb = 44
button1.Paint = function( pnl, w, h )
local color = Color( 36, 36, 44)
local pa = 0.1
if not button1:IsHovered() then
colorr = math.Clamp( colorr + pa, 36, 36+5 )
colorg = math.Clamp( colorg + pa, 36, 36+5 )
colorb = math.Clamp( colorb + pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
else
colorr = math.Clamp( colorr - pa, 36, 36+5 )
colorg = math.Clamp( colorg - pa, 36, 36+5 )
colorb = math.Clamp( colorb - pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
end
draw.RoundedBox( 0, 0, 0, w,h-2, color)
draw.RoundedBox( 0, 0, h-2, w,2, Color( 26, 26, 34))
-- draw.RoundedBox( 0, w-2, 0, 2,h, Color( 31, 31, 41))
draw.SimpleText( "> "..sentences["Buy"][lang], "Bariol17", 15, 40/2-17/2-2, Color( 255, 255, 255, 255 ) )
end
nbing = nbing + 1
end
return panelM
end
local function OpenEntitiesPart(MainFrame)
local sizex = 800
local sizey = 600
local panelM = venalib.Panel( sizex-160, sizey-40, 160, 0, MainFrame )
local nbing = 0
for k , v in pairs( ConfigurationMedicMod.MedicShopEntities ) do
local name = v.name or "No name"
local price = v.price or 10
local x = (sizex-160-40-10)/2
local y = 100
local ispair = math.mod( nbing, 2 )
local panelMIng = venalib.Panel( x, y, 10+(10+(x))*ispair, 10 + math.floor(nbing/2) * (y+10), panelM )
panelMIng.Paint = function( pnl, w, h )
draw.RoundedBox( 0, 0, 0, w,h, Color(36, 36, 44))
end
local icon = vgui.Create( "SpawnIcon", panelMIng )
icon:SetPos( 10, 10 )
icon:SetSize( 80, 80 )
icon:SetModel( v.model or "" )
function icon:LayoutEntity( Entity ) return end
local text = venalib.Label( sentences["Test tube"][lang]..": "..name, 14, x-100-20, 30, 110, 10, Color(255,255,255), panelMIng)
text:SetWrap(false)
local text2 = venalib.Label( price..ConfigurationMedicMod.MoneyUnit, 14, x-100-20, 70, 110, 10, Color(255,255,255), panelMIng)
text2:SetWrap(false)
local button1 = venalib.Button( "> "..sentences["Buy"][lang], x-100-20, 40, x-(x-100-20)-10, y - 45 , function()
net.Start("MedicMod.BuyMedicJobEntity")
net.WriteString( "entity" )
net.WriteString( k )
net.SendToServer()
end,panelMIng )
local colorr = 36
local colorg = 36
local colorb = 44
button1.Paint = function( pnl, w, h )
local color = Color( 36, 36, 44)
local pa = 0.1
if not button1:IsHovered() then
colorr = math.Clamp( colorr + pa, 36, 36+5 )
colorg = math.Clamp( colorg + pa, 36, 36+5 )
colorb = math.Clamp( colorb + pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
else
colorr = math.Clamp( colorr - pa, 36, 36+5 )
colorg = math.Clamp( colorg - pa, 36, 36+5 )
colorb = math.Clamp( colorb - pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
end
draw.RoundedBox( 0, 0, 0, w,h-2, color)
draw.RoundedBox( 0, 0, h-2, w,2, Color( 26, 26, 34))
-- draw.RoundedBox( 0, w-2, 0, 2,h, Color( 31, 31, 41))
draw.SimpleText( "> "..sentences["Buy"][lang], "Bariol17", 15, 40/2-17/2-2, Color( 255, 255, 255, 255 ) )
end
nbing = nbing + 1
end
return panelM
end
local function OpenWeaponsPart(MainFrame)
local sizex = 800
local sizey = 600
local panelM = venalib.Panel( sizex-160, sizey-40, 160, 0, MainFrame )
local nbing = 0
for k , v in pairs( ConfigurationMedicMod.MedicShopWeapons ) do
local name = v.name or "No name"
local price = v.price or 10
local x = (sizex-160-40-10)/2
local y = 100
local ispair = math.mod( nbing, 2 )
local panelMIng = venalib.Panel( x, y, 10+(10+(x))*ispair, 10 + math.floor(nbing/2) * (y+10), panelM )
panelMIng.Paint = function( pnl, w, h )
draw.RoundedBox( 0, 0, 0, w,h, Color(36, 36, 44))
end
local icon = vgui.Create( "SpawnIcon", panelMIng )
icon:SetPos( 10, 10 )
icon:SetSize( 80, 80 )
icon:SetModel( v.model or "" )
function icon:LayoutEntity( Entity ) return end
local text = venalib.Label( sentences["Test tube"][lang]..": "..name, 14, x-100-20, 30, 110, 10, Color(255,255,255), panelMIng)
text:SetWrap(false)
local text2 = venalib.Label( price..ConfigurationMedicMod.MoneyUnit, 14, x-100-20, 70, 110, 10, Color(255,255,255), panelMIng)
text2:SetWrap(false)
local button1 = venalib.Button( "> "..sentences["Buy"][lang], x-100-20, 40, x-(x-100-20)-10, y - 45 , function()
net.Start("MedicMod.BuyMedicJobEntity")
net.WriteString( "weapon" )
net.WriteString( k )
net.SendToServer()
end,panelMIng )
local colorr = 36
local colorg = 36
local colorb = 44
button1.Paint = function( pnl, w, h )
local color = Color( 36, 36, 44)
local pa = 0.1
if not button1:IsHovered() then
colorr = math.Clamp( colorr + pa, 36, 36+5 )
colorg = math.Clamp( colorg + pa, 36, 36+5 )
colorb = math.Clamp( colorb + pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
else
colorr = math.Clamp( colorr - pa, 36, 36+5 )
colorg = math.Clamp( colorg - pa, 36, 36+5 )
colorb = math.Clamp( colorb - pa, 44, 44+5 )
color = Color( colorr, colorg, colorb, 255 )
end
draw.RoundedBox( 0, 0, 0, w,h-2, color)
draw.RoundedBox( 0, 0, h-2, w,2, Color( 26, 26, 34))
-- draw.RoundedBox( 0, w-2, 0, 2,h, Color( 31, 31, 41))
draw.SimpleText( "> "..sentences["Buy"][lang], "Bariol17", 15, 40/2-17/2-2, Color( 255, 255, 255, 255 ) )
end
nbing = nbing + 1
end
return panelM
end
local function OpenGuidePage( MainFrame )
local sizex = 800
local sizey = 600
local panelM = venalib.Panel( sizex-160, sizey-40, 160, 0, MainFrame )
local GuideText = sentences.GuideText[lang]
local htmlc = [[<style>
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
background: #383840;
}
::-webkit-scrollbar-thumb {
background: #555;
}
::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>]]
for _, tab in pairs( GuideText ) do
local text = tab[1] or ""
local size = tab[2] or 15
-- local TextLabel = vgui.Create( "DLabel", panelM )
-- TextLabel:SetPos( 10, pos )
-- TextLabel:SetText( text )
-- TextLabel:SetWrap( true )
-- TextLabel:SetFont("Bariol"..size)
-- TextLabel:SetWide(sizex-160-10)
-- TextLabel:SetAutoStretchVertical( true )
htmlc = htmlc..'<font size="'..(size/4)..'" face="Bariol Regular" color="white">'..text..'</font></br></br>'
-- local sx, sy = TextLabel:GetSize()
-- pos = pos + sy
end
local html = vgui.Create( "DHTML" , panelM )
html:SetSize( sizex-160, sizey-40 )
html:SetHTML( htmlc )
-- local panelM2 = venalib.Panel( 1, 1000, 160, 0, panelM )
-- local panelM1Title = venalib.Label( "Comment cuisiner?", 20, sizex-160, 20, 20, 10 , Color(255,255,255), panelM )
-- panelM1Title:SetWrap(false)
-- local panelM1desc = venalib.Label( [[testen
-- effet
-- oui]], 20, sizex-160, 20, 20, 30 , Color(255,255,255), panelM )
-- local panelM2Title = venalib.Label( "Comment utiliser l'ecran et le terminal?", 20, sizex-160, 20, 20, 350 , Color(255,255,255), panelM )
-- panelM2Title:SetWrap(false)
return panelM
end
local function OpenMedicinesPart(MainFrame)
local rn = 0
local panelB = venalib.Panel( sizex-160, sizey-40, 160, 0, MainFrame )
for k, v in pairs( ConfigurationMedicMod.Drugs ) do
local panel1 = venalib.Panel( sizex-160, 100, 0, 100*rn, panelB )
local panelM1text = venalib.Label( k, 15, 200, 15, 10, 10, Color(255,255,255), panel1 )
local icon = vgui.Create( "SpawnIcon", panel1 )
icon:SetSize( 60, 60 )
icon:SetPos(15, 30)
icon:SetModel( "models/medicmod/drug/drug.mdl" )
local ingnum = 0
for a, b in pairs( v ) do
if a == "func" or a == "price" then continue end
local panelM1Ing1 = venalib.Label( "? "..a, 15, sizex-160-100-20-100, 15, 60+15+5, 32 + 15 * ingnum, Color(255,255,255), panel1 )
panelM1Ing1:SetWrap( false )
ingnum = ingnum + 1
end
local buttonR = venalib.Button( sentences["Buy"][lang].. "( "..v.price..ConfigurationMedicMod.MoneyUnit.." )", 100, 35, sizex-160-100-20, 40, function()
net.Start("MedicMod.BuyMedicJobEntity")
net.WriteString( k )
net.WriteString( "drug_medicmod_s" )
net.SendToServer()
end,panel1 )
rn = rn + 1
end
return panelB
end
local function OpenMainUI()
local actualPart
local MainFrame = venalib.Frame( sizex,sizey )
MainFrame.Paint = function( pnl, w, h )
draw.RoundedBox( 0, 0, 0, w,h, Color(36, 36, 44))
end
local button1 = venalib.Button( "> "..sentences["Test tube"][lang], 160, 40, 0, 80, function() if ispanel(actualPart) then actualPart:Remove() end actualPart = OpenTestTubesPart(MainFrame) end,MainFrame )
local button2 = venalib.Button( "> "..sentences["Drugs"][lang], 160, 40, 0, 40, function() if ispanel(actualPart) then actualPart:Remove() end actualPart = OpenMedicinesPart(MainFrame) end,MainFrame )
local button2 = venalib.Button( "> Guide", 160, 40, 0, 0, function() if ispanel(actualPart) then actualPart:Remove() end actualPart = OpenGuidePage(MainFrame) end,MainFrame )
local button2 = venalib.Button( "> Entities", 160, 40, 0, 120, function() if ispanel(actualPart) then actualPart:Remove() end actualPart = OpenEntitiesPart(MainFrame) end,MainFrame )
local button2 = venalib.Button( "> Weapons", 160, 40, 0, 160, function() if ispanel(actualPart) then actualPart:Remove() end actualPart = OpenWeaponsPart(MainFrame) end,MainFrame )
actualPart = OpenTestTubesPart( MainFrame )
end
net.Receive("MedicMod.OpenMedicMenu", function()
OpenMainUI()
end)

View File

@@ -0,0 +1,118 @@
-- NotificationTable_Venatuss = NotificationTable_Venatuss or {}
-- function MedicNotif( msg, time )
-- local time = time or 10
-- NotificationTable_Venatuss[#NotificationTable_Venatuss + 1] = {
-- text = msg,
-- apptime = CurTime() + 0.2,
-- timeremove = CurTime() + 0.2 + 1 + time,
-- type = "medic",
-- }
-- end
-- local iconMat = Material( "materials/notify_icon.png" )
-- local iconMatR = Material( "materials/notify_rect.png" )
-- hook.Add("HUDPaint", "MedicMod.HUDNotifications", function()
-- for k, v in pairs( NotificationTable_Venatuss ) do
-- if v.type == "medic" then
-- if v.timeremove - CurTime() < 0 then table.remove(NotificationTable_Venatuss,k) continue end
-- local alpha = ( math.Clamp(CurTime() - v.apptime, 0 , 1) )
-- local posy = ScrH() - 200 - 60 * k - 40 * ( 1 - ( math.Clamp(CurTime() - v.apptime, 0 , 1) ) )
-- local posx = math.Clamp(v.timeremove - CurTime(),0,0.25) * 4 * 30 + (0.25 - math.Clamp(v.timeremove - CurTime(),0,0.25)) * 4 * - 340
-- surface.SetFont( "MedicModFont20" )
-- local textsize = select( 1,surface.GetTextSize( v.text ) )
-- surface.SetDrawColor( 255, 255, 255, 255 * alpha )
---- surface.DrawRect( posx + 50, posy, 20 + textsize, 40 )
-- surface.SetMaterial( iconMat )
-- surface.DrawTexturedRect( posx - 20, posy - 18 , 75,75 )
-- surface.SetMaterial( iconMatR )
-- surface.DrawTexturedRect( posx + 75 - 34, posy - 17.5 , textsize + 30, 75 )
-- surface.SetTextPos( posx + 50 + 10, posy + 10 )
-- surface.SetTextColor( 255,255,255, 255 * alpha)
-- surface.DrawText( v.text )
-- end
-- end
-- end)
NotificationTable_Venatuss = NotificationTable_Venatuss or {}
surface.CreateFont( "Bariol20", {
font = "Bariol Regular", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name
extended = false,
size = 20,
weight = 750,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
} )
function MedicNotif( msg, time )
local time = time or 10
NotificationTable_Venatuss[#NotificationTable_Venatuss + 1] = {
text = msg,
apptime = CurTime() + 0.2,
timeremove = CurTime() + 0.2 + 1 + time,
type = "medic",
}
end
local iconMat = Material( "materials/heart_attack_icon.png" )
hook.Add("HUDPaint", "MedicMod.HUDNotifications", function()
for k, v in pairs( NotificationTable_Venatuss ) do
if v.type == "medic" then
if v.timeremove - CurTime() < 0 then table.remove(NotificationTable_Venatuss,k) continue end
local alpha = ( math.Clamp(CurTime() - v.apptime, 0 , 1) )
local posy = ScrH() - 200 - 60 * k - 40 * ( 1 - ( math.Clamp(CurTime() - v.apptime, 0 , 1) ) )
local posx = math.Clamp(v.timeremove - CurTime(),0,0.25) * 4 * 30 + (0.25 - math.Clamp(v.timeremove - CurTime(),0,0.25)) * 4 * - 340
surface.SetFont( "Bariol20" )
local x,y = surface.GetTextSize( v.text )
draw.RoundedBox( 5, posx, posy , 60, 40, Color(0, 131, 167,255 * alpha ) )
surface.SetDrawColor( 255, 255, 255, 255 * alpha )
surface.DrawRect( posx + 50, posy, 20 + x, 40 )
surface.SetMaterial( iconMat )
surface.DrawTexturedRect( posx + 10, posy + 5, 30, 30 )
surface.SetTextPos( posx + 50 + 10, posy + 40/2-y/2 )
surface.SetTextColor( 0, 0, 0, 255 * alpha)
surface.DrawText( v.text )
end
end
end)
net.Receive("MedicMod:NotifyPlayer", function()
local msg = net.ReadString()
local time = net.ReadInt( 32 )
MedicNotif( msg, time )
end)

View File

@@ -0,0 +1,494 @@
local meta = FindMetaTable( "Player" )
local lang = ConfigurationMedicMod.Language
local sentences = ConfigurationMedicMod.Sentences
function meta:MedicModDamages()
local dmg = 0
if self:IsBleeding() then
dmg = dmg + ConfigurationMedicMod.DamagePerSecsDuringBleeding * 4
end
if self:IsPoisoned() then
dmg = dmg + ConfigurationMedicMod.DamagePerSecsDuringPoisoned * 4
end
return dmg or 0
end
function meta:CreateMedicTimer()
timer.Create("MedicMod"..self:EntIndex(), 4, 0, function()
if not IsValid( self ) or not self:Alive() then return end
local world = game.GetWorld()
local d = DamageInfo()
d:SetDamage( self:MedicModDamages() )
d:SetAttacker( world )
d:SetInflictor( world )
if self:IsBleeding() then
d:SetDamageType( DMG_MEDICMODBLEEDING )
-- bleeding effect
local bone = self:GetBonePosition(math.random(1, self:GetBoneCount() - 1))
if bone then
local ef = EffectData()
ef:SetOrigin(bone)
util.Effect("BloodImpact", ef, true, true)
end
-- bleeding decals
if ConfigurationMedicMod.DecalsBleeding then
local src = self:LocalToWorld(self:OBBCenter())
for i = 1, 12 do
local dir = VectorRand() * self:GetModelRadius() * 1.4
util.Decal("Blood", src - dir, src + dir)
end
end
else
d:SetDamageType( DMG_MEDICMOD )
end
local health = self:Health()
self:TakeDamageInfo( d )
self:SetHealth(health-self:MedicModDamages())
if self:Health() <= 0 and self:Alive() then
self:Kill()
end
end)
end
function meta:SetBleeding( bool )
if self:HasGodMode() then return end
if not ConfigurationMedicMod.CanGetBleeding then return end
if table.HasValue( ConfigurationMedicMod.TeamsCantGetBleeding, self:Team() ) then return end
self:SetNWBool("Bleeding", bool )
if not bool then
if timer.Exists( "MedicMod"..self:EntIndex() ) then
if not self:IsPoisoned() then
timer.Destroy("MedicMod"..self:EntIndex())
end
end
return
end
if timer.Exists( "MedicMod"..self:EntIndex() ) then return end
hook.Run( "onPlayerStartsBleeding", self )
self:CreateMedicTimer()
end
function meta:SetMorphine( bool )
self:SetNWBool("Morphine", bool )
end
function meta:SetHeartAttack( bool )
self:SetNWBool("HeartAttack", bool )
if timer.Exists( "MedicMod"..self:EntIndex() ) then
timer.Destroy("MedicMod"..self:EntIndex())
end
end
function meta:SetPoisoned( bool )
if self:HasGodMode() then return end
if not ConfigurationMedicMod.CanGetPoisoned then return end
if table.HasValue( ConfigurationMedicMod.TeamsCantGetPoisoned, self:Team() ) then return end
self:SetNWBool("Poisoned", bool )
if not bool then
if timer.Exists( "MedicMod"..self:EntIndex() ) then
if not self:IsBleeding() then
timer.Destroy("MedicMod"..self:EntIndex())
end
end
return
end
if timer.Exists( "MedicMod"..self:EntIndex() ) then return end
hook.Run( "onPlayerPoisoned", self )
self:CreateMedicTimer()
end
local FractureHitGroups = {}
FractureHitGroups["legs"] = {
[HITGROUP_LEFTLEG] = true,
[HITGROUP_RIGHTLEG] = true,
}
FractureHitGroups["arms"] = {
[HITGROUP_LEFTARM] = true,
[HITGROUP_RIGHTARM] = true,
}
function meta:SetFracture( bool, hitgroup )
if self:HasGodMode() then return end
if not ConfigurationMedicMod.CanGetFractures then return end
if table.HasValue( ConfigurationMedicMod.TeamsCantGetFracture, self:Team() ) then return end
if bool then
self:SetNWBool("Fracture", bool )
if not self.Fractures then self.Fractures = {} end
if self.Fractures[hitgroup] then return end
self.Fractures[hitgroup] = true
if FractureHitGroups["legs"][hitgroup] then
self:MedicNotif(sentences["You broke your leg, your speed is reduced"][lang])
if self.SpeedReduced then return end
self.MMFWalkSpeed = self:GetWalkSpeed()
self.MMFRunSpeed = self:GetRunSpeed()
self:SetRunSpeed(ConfigurationMedicMod.FracturePlayerSpeed)
self:SetWalkSpeed(ConfigurationMedicMod.FracturePlayerSpeed)
self.SpeedReduced = true
elseif FractureHitGroups["arms"][hitgroup] then
self:MedicNotif(sentences["You broke your arm, you can't use any weapon"][lang])
self:SelectWeapon( "" )
self.CantSwitchWeaponMF = true
end
hook.Run( "onPlayerBreaksBone", self, hitgroup )
else
if not self.Fractures then self.Fractures = {} end
if FractureHitGroups["legs"][hitgroup] then
if self.Fractures[hitgroup] then
self.Fractures[hitgroup] = nil
end
for k, v in pairs( FractureHitGroups["legs"] ) do
if self.Fractures[k] then
return
end
end
if not self.MMFRunSpeed or not self.MMFWalkSpeed then return end
self:SetRunSpeed(self.MMFRunSpeed)
self:SetWalkSpeed(self.MMFWalkSpeed)
self.SpeedReduced = false
elseif FractureHitGroups["arms"][hitgroup] then
if self.Fractures[hitgroup] then
self.Fractures[hitgroup] = nil
end
for k, v in pairs( FractureHitGroups["arms"] ) do
if self.Fractures[k] then
return
end
end
self.CantSwitchWeaponMF = false
end
for k, v in pairs( self.Fractures ) do
if FractureHitGroups["legs"][ k ] or FractureHitGroups["arms"][ k ] then
return
end
end
self:SetNWBool("Fracture", false)
self:MedicNotif(sentences["You have no more fracture"][lang])
end
end
function meta:GetFractures()
return self.Fractures or nil
end
function meta:CreateDeathRagdoll()
-- create the ragdoll
local ragdoll = ents.Create("prop_ragdoll")
ragdoll:SetPos(self:GetPos())
ragdoll:SetAngles( self:GetAngles() )
ragdoll:SetModel(self:GetModel())
ragdoll:SetOwner( self )
ragdoll:SetDeathRagdoll( true )
-- set bones of the ragdoll at the same pos than bones of the player
local gpobc = ragdoll:GetPhysicsObjectCount() - 1
for i=0, gpobc do
local bone = self:GetPhysicsObjectNum(i)
if IsValid(bone) then
local bonepos, boneang = self:GetBonePosition(ragdoll:TranslatePhysBoneToBone(i))
if bonepos and boneang then
bone:SetPos(bonepos)
bone:SetAngles(boneang)
end
end
end
ragdoll:Spawn()
ragdoll:Activate()
ragdoll:AddEFlags( EFL_IN_SKYBOX )
-- make a prop to allow the player to pickup the ragdoll
local pickupProp = ents.Create("prop_physics")
pickupProp:SetModel("models/hunter/blocks/cube025x025x025.mdl")
pickupProp:SetPos(ragdoll:GetPos())
pickupProp:SetNoDraw(true)
pickupProp:Spawn()
pickupProp:SetCollisionGroup(COLLISION_GROUP_WORLD)
ragdoll.Prop = pickupProp
pickupProp.ragdoll = ragdoll
constraint.Weld(ragdoll, pickupProp, 0, 0, 0, false)
self.DeathRagdoll = ragdoll
if CLOTHESMOD then self:CM_ApplyRagModel( ragdoll ) end
return ragdoll
end
function meta:Stabilize( medic )
if self:IsBleeding() then return end
if self:IsPoisoned() then return end
if self:GetHeartAttack() then return end
self.NextSpawnTime = ConfigurationMedicMod.TimeBeforeRespawnIfStable + CurTime()
net.Start("MedicMod.Respawn") net.WriteInt(self.NextSpawnTime, 32) net.Send(self)
self.Stable = true
self:MedicNotif( sentences["Your condition has been stabilized"][lang], 10)
hook.Run( "onPlayerStabilized", self, medic )
if not IsValid( medic ) then return end
medic:MedicNotif( sentences["You stabilized the wounded"][lang], 10)
end
function meta:MedicalRespawn()
local pos
if not IsValid( self.DeathRagdoll ) or not self.DeathRagdoll:IsDeathRagdoll() then
pos = self:GetPos()
else
if IsValid(self.DeathRagdoll.Rope) then
self.DeathRagdoll.Rope:SetParent( nil )
if self.DeathRagdoll.Rope.Elec and IsValid( self.DeathRagdoll.Rope.Elec ) then
self.DeathRagdoll.Rope.Elec:SetPatient( nil )
end
end
pos = self.DeathRagdoll:GetPos()
end
self:MedicNotif( sentences["You have been saved"][lang], 10)
-- Save current weapons and ammo before Spawn() resets them
self.WeaponsStripped = {}
for k, v in pairs( self:GetWeapons() ) do
table.insert(self.WeaponsStripped, v:GetClass())
end
self.AmmoStripped = {}
for k, v in pairs( self:GetAmmo() ) do
self.AmmoStripped[k] = v
end
self:Spawn()
self:SetPos( pos )
local weaponsstripped = self.WeaponsStripped or {}
for k, v in pairs( weaponsstripped ) do
self:Give( v )
end
local ammostripped = self.AmmoStripped or {}
for k, v in pairs( ammostripped ) do
self:SetAmmo( v, k )
end
hook.Run( "onPlayerRevived", self )
end
function meta:StartOperation( bed )
local pos = self:GetPos()
local ang = self:GetAngles()
local hbed = ents.Create("prop_vehicle_prisoner_pod")
hbed:SetModel("models/vehicles/prisoner_pod_inner.mdl")
hbed:SetPos( bed:GetPos() + bed:GetAngles():Up() * 22 + bed:GetAngles():Right() * -30 )
hbed:SetAngles( bed:GetAngles() + Angle(-90,0,90))
hbed:SetNoDraw(true)
hbed:SetCollisionGroup(COLLISION_GROUP_WORLD)
hbed:SetSolid(SOLID_NONE)
hbed.locked = true
bed.ragdoll = hbed
self:EnterVehicle(hbed)
self:MedicNotif( sentences["You are having surgery"][lang], ConfigurationMedicMod.SurgicalOperationTime)
self:Freeze( true )
hook.Run( "onPlayerStartsOperation", self )
timer.Simple( ConfigurationMedicMod.SurgicalOperationTime, function()
if not IsValid(self) or not IsValid(bed) or not IsValid(hbed) then return end
self:Freeze( false )
self:SetHealth( self:GetMaxHealth() )
if not self.Fractures then self.Fractures = {} end
for k, v in pairs( self.Fractures ) do
self:SetFracture( false, k )
end
self:SetBleeding( false )
hbed:Remove()
timer.Simple(0.2, function()
self:SetPos( pos )
self:SetEyeAngles( ang )
end)
bed.ragdoll = nil
end)
end
function meta:HaveFractures()
local fract = false
if not self.Fractures then return false end
for k, v in pairs( self.Fractures ) do
if FractureHitGroups["legs"][ k ] or FractureHitGroups["arms"][ k ] then
fract = true
break
end
end
return fract
end
function StartMedicAnimation( ply, id )
ply:SetNWString("MedicPlayerModel", ply:GetModel())
ply:SetModel("models/medicmod/player/medic_anims.mdl")
ply:SetRenderMode(RENDERMODE_TRANSALPHA)
ply:SetColor(Color(0,0,0,0))
ply:SetNWInt("MedicActivity", id )
ply:Freeze( true )
-- network animation
net.Start("MedicMod.PlayerStartAnimation")
net.Broadcast()
end
function StopMedicAnimation( ply )
ply:SetNWInt("MedicActivity", 0 )
ply:SetModel( ply:GetNWString("MedicPlayerModel") )
ply:SetColor(Color(255,255,255,255))
ply:SetNWString("MedicPlayerModel", nil)
ply:Freeze( false )
-- network animation
net.Start("MedicMod.PlayerStopAnimation")
net.Broadcast()
end
function IsBleedingDamage( dmg )
local isdmg = false
for k, v in pairs( ConfigurationMedicMod.DamageBleeding ) do
if not v then continue end
if dmg:IsDamageType( k ) then
isdmg = true
end
end
return isdmg
end
function IsPoisonDamage( dmg )
local isdmg = false
for k, v in pairs( ConfigurationMedicMod.DamagePoisoned ) do
if dmg:IsDamageType( k ) then
isdmg = true
end
end
return isdmg
end
local ent = FindMetaTable( "Entity" )
function ent:SetDeathRagdoll( bool )
self:SetNWBool("IsDeathRagdoll", bool )
end

View File

@@ -0,0 +1,559 @@
local lang = ConfigurationMedicMod.Language
local sentences = ConfigurationMedicMod.Sentences
-- Delete the timer
hook.Add("PlayerDisconnected", "PlayerDisconnected.MedicMod", function( ply )
StopMedicAnimation( ply )
if ply.RagdollHeartMassage then
if IsValid( ply.RagdollHeartMassage ) && IsValid( ply.RagdollHeartMassage:GetOwner() ) then
ply.RagdollHeartMassage:GetOwner().NextSpawnTime = CurTime() + ply.RagdollHeartMassage:GetOwner().AddToSpawnTime
ply.RagdollHeartMassage.IsHeartMassage = false
net.Start("MedicMod.Respawn")
net.WriteInt(ply.RagdollHeartMassage:GetOwner().NextSpawnTime,32)
net.Send(ply.RagdollHeartMassage:GetOwner())
end
end
if timer.Exists( "MedicMod"..ply:EntIndex() ) then
timer.Destroy("MedicMod"..ply:EntIndex())
end
-- remove the death ragdoll
if IsValid( ply.DeathRagdoll ) then
if IsValid( ply.DeathRagdoll.Prop ) then
ply.DeathRagdoll.Prop:Remove()
end
ply.DeathRagdoll:Remove()
end
end)
-- Respawn
hook.Add("PlayerSpawn", "PlayerSpawn.MedicMod", function( ply )
ply:SetBleeding( false )
ply:SetHeartAttack( false )
ply:SetPoisoned( false )
if ply:GetFractures() then
-- cure fractures
for k, v in pairs( ply:GetFractures() ) do
ply:SetFracture(false, k)
end
end
-- remove the death ragdoll
if IsValid( ply.DeathRagdoll ) then
if IsValid( ply.DeathRagdoll.Prop ) then
ply.DeathRagdoll.Prop:Remove()
end
ply.DeathRagdoll:Remove()
if IsValid(ply.DeathRagdoll.Rope) then
ply.DeathRagdoll.Rope:SetParent( nil )
if ply.DeathRagdoll.Rope.Elec and IsValid( ply.DeathRagdoll.Rope.Elec ) then
ply.DeathRagdoll.Rope.Elec:SetPatient( nil )
end
end
end
ply:UnSpectate()
ply.NextSpawnTime = 0
end)
-- Stop death sound
hook.Add("PlayerDeathSound", "PlayerDeathSound.MedicMod", function()
return true
end)
-- Bleeding
hook.Add("EntityTakeDamage", "EntityTakeDamage.MedicMod", function( ply, dmg )
if not IsValid(ply) or not ply:IsPlayer() then return end
-- Fix for LVS/Vehicles: ignore blast/shell damage if player is in a vehicle and damage is self-inflicted
if (ply:InVehicle()) then
local vehicle = ply:GetVehicle()
local attacker = dmg:GetAttacker()
local inflictor = dmg:GetInflictor()
if (attacker == ply or attacker == vehicle or inflictor == vehicle) and (dmg:IsDamageType(DMG_BLAST) or dmg:IsDamageType(DMG_BLAST_SURFACE)) then
return
end
end
local dmgtype = dmg:GetDamageType()
-- break a bone
if dmg:IsFallDamage() then
if dmg:GetDamage() >= ConfigurationMedicMod.MinimumDamageToGetFractures then
ply:SetFracture(true, HITGROUP_RIGHTLEG)
ply:SetFracture(true, HITGROUP_LEFTLEG)
end
end
if IsBleedingDamage( dmg ) and dmg:GetDamage() >= ConfigurationMedicMod.MinimumDamageToGetBleeding then
ply:SetBleeding( true )
end
if IsPoisonDamage( dmg ) then ply:SetPoisoned( true ) end
end)
-- Set heart attack
hook.Add("DoPlayerDeath", "DoPlayerDeath.MedicMod", function( ply, att, dmg )
StopMedicAnimation( ply )
if ply.RagdollHeartMassage then
if IsValid( ply.RagdollHeartMassage ) && IsValid( ply.RagdollHeartMassage:GetOwner() ) then
ply.RagdollHeartMassage:GetOwner().NextSpawnTime = CurTime() + ply.RagdollHeartMassage:GetOwner().AddToSpawnTime
ply.RagdollHeartMassage.IsHeartMassage = false
net.Start("MedicMod.Respawn")
net.WriteInt(ply.RagdollHeartMassage:GetOwner().NextSpawnTime,32)
net.Send(ply.RagdollHeartMassage:GetOwner())
end
end
local dmgtype = dmg:GetDamageType()
local dmgimpact = dmg:GetDamage()
if IsBleedingDamage( dmg ) or ConfigurationMedicMod.DamageBurn[dmgtype] then
if dmgtype == DMG_MEDICMODBLEEDING then
ply:MedicNotif(sentences["His heart no longer beats"][lang], 10)
end
ply:SetHeartAttack( true )
ply:MedicNotif(sentences["You fell unconscious following a heart attack"][lang], 10)
else
if IsPoisonDamage(dmg) then
ply:SetPoisoned( true )
end
if IsBleedingDamage( dmg ) and dmgimpact >= ConfigurationMedicMod.MinimumDamageToGetBleeding then
ply:SetBleeding( true )
end
ply:SetHeartAttack( true )
ply:MedicNotif(sentences["You fell unconscious following a heart attack"][lang], 10)
end
end)
-- Create the death ragdoll, etc.
hook.Add("PlayerDeath", "PlayerDeath.MedicMod", function( victim, inf, att )
-- Save player weapons
victim.WeaponsStripped = {}
for k, v in pairs( victim:GetWeapons() ) do
table.insert(victim.WeaponsStripped,v:GetClass())
end
-- Save player ammo
victim.AmmoStripped = {}
for k, v in pairs( victim:GetAmmo() ) do
victim.AmmoStripped[k] = v
end
-- set the next respawn time
timer.Simple( 0, function()
local timebeforerespawn = CurTime()+ConfigurationMedicMod.TimeBeforeRespawnIfNoConnectedMedics
for k, v in pairs( player.GetAll() ) do
if table.HasValue( ConfigurationMedicMod.MedicTeams, v:Team() ) then
timebeforerespawn = CurTime()+ConfigurationMedicMod.TimeBeforeRespawn
break
end
end
victim.NextSpawnTime = timebeforerespawn
net.Start("MedicMod.Respawn")
net.WriteInt(timebeforerespawn,32)
net.Send(victim)
end )
if not IsValid( victim ) or not victim:GetHeartAttack() then return end
if victim:InVehicle() then victim:ExitVehicle() end
-- Create death ragdoll
local rag = victim:CreateDeathRagdoll()
-- Remove ragdoll ent
timer.Simple(0.01, function()
if(victim:GetRagdollEntity() != nil and victim:GetRagdollEntity():IsValid()) then
victim:GetRagdollEntity():Remove()
end
end)
-- Set the view on the ragdoll
victim:Spectate( OBS_MODE_DEATHCAM )
victim:SpectateEntity( rag )
end)
-- Determine if the player can respawn
hook.Add("PlayerDeathThink", "PlayerDeathThink.MedicMod", function( pl )
if not ( pl.NextSpawnTime ) then pl.NextSpawnTime = 0 end
if pl.NextSpawnTime == -1 then return false end
if pl.NextSpawnTime > CurTime() then return false end
if ConfigurationMedicMod.ForceRespawn then
pl:Spawn()
end
end)
hook.Add("PlayerSwitchWeapon", "PlayerSwitchWeapon.MedicMod", function( ply, old, new )
if not IsValid( old ) or not IsValid( ply ) then return end
-- prevent switch weapon if the player is doing a heart massage
if old:GetClass() == "heart_massage" && ply:GetMedicAnimation() != 0 then
return true
end
if ply.CantSwitchWeapon then
return true
end
if ply.CantSwitchWeaponMF and ConfigurationMedicMod.CanBreakArms then
return true
end
end)
-- Start animations when player join
hook.Add("PlayerInitialSpawn", "PlayerInitialSpawn.MedicMod", function( ply )
timer.Simple(10, function()
net.Start("MedicMod.PlayerStartAnimation")
net.Send( ply )
end)
end)
--[[
local function MedicMod_DropCarriedRagdoll(ply, throw)
if not IsValid(ply) then return end
local rag = ply.CarryingRagdoll
if not IsValid(rag) then
ply.CarryingRagdoll = nil
ply:SetNWBool("CarryingRagdoll", false)
return
end
rag:SetParent(nil)
rag:SetMoveType(MOVETYPE_VPHYSICS)
local phys = rag:GetPhysicsObject()
if IsValid(phys) then
phys:EnableMotion(true)
phys:Wake()
if throw then
phys:SetVelocity(ply:GetAimVector() * 450 + ply:GetVelocity() * 0.5 + Vector(0,0,125))
end
end
rag:SetNWEntity("CarriedBy", NULL)
rag:SetNWBool("IsRagdollCarried", false)
ply.CarryingRagdoll = nil
ply:SetNWBool("CarryingRagdoll", false)
ply:MedicNotif(ConfigurationMedicMod.Sentences["You dropped the corpse"][ConfigurationMedicMod.Language], 5)
end
hook.Add("PlayerButtonDown", "PlayerButtonDown.MedicMod.CarryRagdoll", function(ply, button)
if not IsValid(ply) or not ply:Alive() or button ~= KEY_E then return end
if IsValid(ply.CarryingRagdoll) then
MedicMod_DropCarriedRagdoll(ply, true)
return
end
local trace = ply:GetEyeTraceNoCursor()
local ent = trace.Entity
if not IsValid(ent) or not ent:IsDeathRagdoll() then return end
if trace.HitPos:Distance(ply:GetPos()) > 120 then return end
if ent:GetNWEntity("CarriedBy", NULL):IsValid() then return end
if ent:GetNWBool("IsRagdollCarried", false) then return end
ent:SetMoveType(MOVETYPE_NONE)
ent:SetParent(ply)
ent:SetLocalPos(Vector(10, -12, 18))
ent:SetLocalAngles(Angle(90, 0, 0))
ent:SetNWEntity("CarriedBy", ply)
ent:SetNWBool("IsRagdollCarried", true)
ply.CarryingRagdoll = ent
ply:SetNWBool("CarryingRagdoll", true)
ply:MedicNotif(ConfigurationMedicMod.Sentences["You attached the corpse on your back"][ConfigurationMedicMod.Language], 5)
end)
hook.Add("Think", "Think.MedicMod.CarryRagdoll", function()
for _, ply in ipairs(player.GetAll()) do
if not IsValid(ply) then continue end
local rag = ply.CarryingRagdoll
if not IsValid(rag) then continue end
if not ply:Alive() then
MedicMod_DropCarriedRagdoll(ply, false)
continue
end
local eye = ply:EyeAngles()
local backPos = ply:GetPos() + ply:GetForward() * -8 + ply:GetRight() * 4 + Vector(0,0,18)
rag:SetPos(backPos)
rag:SetAngles(eye + Angle(90,0,0))
end
end)
]]
-- When a player spawn an ambulance
hook.Add("PlayerSpawnedVehicle", "PlayerSpawnedVehicle.MedicMod", function( ply, ent )
if not IsValid( ent ) then return end
if ConfigurationMedicMod.Vehicles[ent:GetModel()] then
local button = ents.Create("ambulance_button_medicmod")
button:Spawn()
button:SetPos( ent:LocalToWorld(ConfigurationMedicMod.Vehicles[ent:GetModel()].buttonPos) )
button:SetAngles( ent:LocalToWorldAngles(ConfigurationMedicMod.Vehicles[ent:GetModel()].buttonAngle) )
button:SetParent( ent )
ent.Button = button
local stretcher = ents.Create("stretcher_medicmod")
stretcher:Spawn()
stretcher:SetPos(ent:LocalToWorld(ConfigurationMedicMod.Vehicles[ent:GetModel()].stretcherPos))
stretcher:SetAngles(ent:LocalToWorldAngles(ConfigurationMedicMod.Vehicles[ent:GetModel()].stretcherAngle))
stretcher:SetParent( ent )
if not ConfigurationMedicMod.Vehicles[ent:GetModel()].drawStretcher then
stretcher:SetRenderMode( RENDERMODE_TRANSALPHA )
stretcher:SetColor( Color(0,0,0,0) )
end
ent.Stretcher = stretcher
ent.SpawnedStretcher = stretcher
end
end)
-- Remove the stretcher when vehicle is removed
hook.Add("EntityRemoved", "EntityRemoved.MedicMod", function( ent )
if not IsValid( ent ) then return end
local stretch = ent.SpawnedStretcher or NULL
if not IsValid( stretch ) then return end
if stretch.ragdoll && IsValid( stretch.ragdoll ) then return end
stretch:Remove()
end)
local FractureHitGroups = {
[HITGROUP_LEFTLEG] = true,
[HITGROUP_RIGHTLEG] = true,
[HITGROUP_LEFTARM] = true,
[HITGROUP_RIGHTARM] = true,
}
-- break a bone
hook.Add("ScalePlayerDamage", "ScalePlayerDamage.MedicMod", function(ply, hitgroup, dmg)
if not FractureHitGroups[hitgroup] then return end
if dmg:GetDamage() < ConfigurationMedicMod.MinimumDamageToGetFractures then return end
ply:SetFracture( true, hitgroup )
end)
-- Save entities
local MedicModSavedEntities = {
["terminal_medicmod"] = true,
["radio_medicmod"] = true,
["npc_health_seller_medicmod"] = true,
["mural_defib_medicmod"] = true,
["electrocardiogram_medicmod"] = true,
["bed_medicmod"] = true,
}
-- Commands
hook.Add("PlayerSay", "PlayerSay.MedicMod", function(ply, text)
if text == "!save_medicmod" and ply:IsSuperAdmin() then
local MedicPos = {}
for k, v in pairs(ents.GetAll()) do
if not MedicModSavedEntities[v:GetClass()] then continue end
MedicPos[#MedicPos + 1] = {
pos = v:GetPos(),
ang = v:GetAngles(),
class = v:GetClass()
}
file.CreateDir("medicmod")
file.Write("medicmod/save_ents.txt", util.TableToJSON(MedicPos))
local filecontent = file.Read("medicmod/save_ents.txt", "DATA")
ConfigurationMedicMod.SavedEnts = util.JSONToTable(filecontent)
end
ply:MedicNotif("Entities saved!")
end
if text == "!remove_medicmod" and ply:IsSuperAdmin() then
if file.Exists("medicmod/save_ents.txt", "DATA") then
file.Delete( "medicmod/save_ents.txt" )
ply:MedicNotif("Entities removed!")
end
local filecontent = file.Read("medicmod/save_ents.txt", "DATA") or ""
ConfigurationMedicMod.SavedEnts = util.JSONToTable(filecontent) or {}
end
if text == "!reviveme" and ply:IsAdmin() and ConfigurationMedicMod.CanUseReviveMeCommand then
ply:MedicalRespawn()
end
if text == "!"..ConfigurationMedicMod.MedicCommand and table.HasValue( ConfigurationMedicMod.MedicTeams, ply:Team() ) then
net.Start("MedicMod.OpenMedicMenu")
net.Send( ply )
end
end)
-- Init the list of ents to spawn
hook.Add("Initialize", "Initialize.MedicMod", function()
if not file.Exists("medicmod/save_ents.txt", "DATA") then return end
local filecontent = file.Read("medicmod/save_ents.txt", "DATA")
ConfigurationMedicMod.SavedEnts = util.JSONToTable(filecontent)
end)
-- spawn ents
hook.Add("InitPostEntity", "InitPostEntity.MedicMod", function()
if not ConfigurationMedicMod.SavedEnts then return end
timer.Simple(1, function()
for k, v in pairs(ConfigurationMedicMod.SavedEnts) do
local ent = ents.Create(v.class)
ent:SetPos( v.pos )
ent:SetAngles( v.ang )
ent:SetPersistent( true )
ent:Spawn()
ent:SetMoveType( MOVETYPE_NONE )
end
end)
end)
hook.Add("PostCleanupMap", "PostCleanupMap.MedicMod", function()
if not ConfigurationMedicMod.SavedEnts then return end
for k, v in pairs(ConfigurationMedicMod.SavedEnts) do
local ent = ents.Create(v.class)
ent:SetPos( v.pos )
ent:SetAngles( v.ang )
ent:SetPersistent( true )
ent:Spawn()
ent:SetMoveType( MOVETYPE_NONE )
end
end)
-- Can change job?
hook.Add("playerCanChangeTeam", "playerCanChangeTeam.MedicMod", function(ply)
if ply.NextSpawnTime and ply.NextSpawnTime > CurTime() then return false end
if ply.NextSpawnTime and ply.NextSpawnTime == -1 then return false end
if ply:GetMedicAnimation() != 0 then return false end
end)
-- if someone change job
hook.Add("OnPlayerChangedTeam", "OnPlayerChangedTeam.MedicMod", function(ply, bef, after)
if ConfigurationMedicMod.HealedOnChangingJob then
ply:SetBleeding( false )
ply:SetHeartAttack( false )
ply:SetPoisoned( false )
if ply:GetFractures() then
-- cure fractures
for k, v in pairs( ply:GetFractures() ) do
ply:SetFracture(false, k)
end
end
-- remove the death ragdoll
if IsValid( ply.DeathRagdoll ) then
if IsValid( ply.DeathRagdoll.Prop ) then
ply.DeathRagdoll.Prop:Remove()
end
ply.DeathRagdoll:Remove()
end
ply:UnSpectate()
else
timer.Simple( 1, function()
if ply:GetFractures() then
for k, v in pairs( ply:GetFractures() ) do
ply:SetFracture(true, k)
end
end
end)
end
if table.HasValue( ConfigurationMedicMod.MedicTeams, ply:Team() ) then
ply:MedicNotif(sentences["You're now a medic, get help with"][lang].." !"..ConfigurationMedicMod.MedicCommand)
end
end)

View File

@@ -0,0 +1,214 @@
util.AddNetworkString("MedicMod.MedicMenu")
util.AddNetworkString("MedicMod.MedicStart")
util.AddNetworkString("MedicMod.BuyMedicEntity")
-- util.AddNetworkString("MedicMod.NotifiyPlayer")
util.AddNetworkString("MedicMod.PlayerStartAnimation")
util.AddNetworkString("MedicMod.ScanRadio")
util.AddNetworkString("MedicMod.Respawn")
util.AddNetworkString("MedicMod.TerminalMenu")
util.AddNetworkString("MedicMod.PlayerStopAnimation")
util.AddNetworkString("MedicMod.OpenMedicMenu")
util.AddNetworkString("MedicMod.BuyMedicJobEntity")
local spamCooldowns = {}
local interval = .1
local function spamCheck(pl, name)
if spamCooldowns[pl:SteamID()] then
if spamCooldowns[pl:SteamID()][name] then
if spamCooldowns[pl:SteamID()][name] > CurTime() then
return false
else
spamCooldowns[pl:SteamID()][name] = CurTime() + interval
return true
end
else
spamCooldowns[pl:SteamID()][name] = CurTime() + interval
return true
end
else
spamCooldowns[pl:SteamID()] = {}
spamCooldowns[pl:SteamID()][name] = CurTime() + interval
return true // They haven't sent shit :P
end
end
net.Receive("MedicMod.MedicStart", function( len, caller )
if not spamCheck( caller, "MedicMod.MedicStart" ) then return end
local ent = net.ReadEntity()
local health = caller:Health()
if caller:GetPos():DistToSqr(ent:GetPos()) > 22500 then return end
if health <= 0 then return end
if health >= caller:GetMaxHealth() and not caller:HaveFractures() then return end
local price = 0
if health < caller:GetMaxHealth() then
price = ( caller:GetMaxHealth() - health ) * ConfigurationMedicMod.HealthUnitPrice
end
if caller:HaveFractures() then
price = price + table.Count(caller.Fractures) * ConfigurationMedicMod.FractureRepairPrice
end
local bed = nil
local dist = -1
for k, v in pairs( ents.FindByClass("bed_medicmod") ) do
if IsValid( v.ragdoll ) then continue end
local ndist = v:GetPos():Distance( caller:GetPos() )
if dist == -1 or dist > ndist then
bed = v
dist = ndist
end
end
if not bed or not IsValid( bed ) then caller:MedicNotif(ConfigurationMedicMod.Sentences["You can't be healed because there is no free bed, retry later"][ConfigurationMedicMod.Language]) return end
if caller:getDarkRPVar("money") < price then caller:MedicNotif(ConfigurationMedicMod.Sentences["You don't have enough money"][ConfigurationMedicMod.Language]) return end
caller:addMoney( -price )
caller:StartOperation( bed )
end)
net.Receive("MedicMod.Respawn",function(len,ply)
if not spamCheck( ply, "MedicMod.Respawn" ) then return end
if ply.NextSpawnTime > CurTime() or ply:Alive() or ply.NextSpawnTime == -1 then return end
ply:Spawn()
end)
net.Receive("MedicMod.BuyMedicEntity", function( len, caller )
if not spamCheck( caller, "MedicMod.BuyMedicEntity" ) then return end
local key = net.ReadInt( 32 )
local ent = net.ReadEntity()
local cfg = ConfigurationMedicMod.Entities[key]
if not IsValid( ent ) then return end
if caller:GetPos():Distance(ent:GetPos()) > 200 then return end
if caller:getDarkRPVar("money") < cfg.price then caller:MedicNotif(ConfigurationMedicMod.Sentences["You don't have enough money"][ConfigurationMedicMod.Language]) return end
cfg.func( caller, cfg.ent, cfg.price )
end)
net.Receive("MedicMod.BuyMedicJobEntity", function( len, caller )
if not spamCheck( caller, "MedicMod.BuyMedicJobEntity" ) then return end
local key = net.ReadString()
local class = net.ReadString()
local spawnedtesttubes = caller.TestTubesSpawned or 0
local spawneddrugs = caller.DrugsSpawned or 0
local spawnedEnts = caller.spawnedEntsMedicMod or {}
if not table.HasValue( ConfigurationMedicMod.MedicTeams, caller:Team() ) then return end
if class == "test_tube_medicmod_s" and spawnedtesttubes < ConfigurationMedicMod.MaxTestTubesSpawnedWithTheShop then
if not ConfigurationMedicMod.Reagents[key] then return end
local price = ConfigurationMedicMod.Reagents[key].price
if caller:getDarkRPVar("money") < price then caller:MedicNotif(ConfigurationMedicMod.Sentences["You don't have enough money"][ConfigurationMedicMod.Language]) return end
caller:addMoney( -price )
local ent = ents.Create("test_tube_medicmod")
ent:SetPos(caller:GetPos() + caller:GetAngles():Forward() * 30 + caller:GetAngles():Up() * 20 )
ent:SetProduct(key)
ent:Spawn()
if CPPI then
ent:CPPISetOwner(caller)
end
undo.Create( ConfigurationMedicMod.Sentences["Test tube"][ConfigurationMedicMod.Language] )
undo.AddEntity( ent )
undo.SetPlayer( caller )
undo.Finish()
ent.TestTubeSpawner = caller
caller.TestTubesSpawned = spawnedtesttubes + 1 or 1
elseif class == "test_tube_medicmod_s" and spawnedtesttubes >= ConfigurationMedicMod.MaxTestTubesSpawnedWithTheShop then
caller:MedicNotif(ConfigurationMedicMod.Sentences["You've reached the limit of"][ConfigurationMedicMod.Language].." "..ConfigurationMedicMod.Sentences["Test tube"][ConfigurationMedicMod.Language])
elseif class == "drug_medicmod_s" and spawneddrugs < ConfigurationMedicMod.MaxDrugsSpawnedWithTheShop then
if not ConfigurationMedicMod.Drugs[key] then return end
local price = ConfigurationMedicMod.Drugs[key].price
if caller:getDarkRPVar("money") < price then caller:MedicNotif(ConfigurationMedicMod.Sentences["You don't have enough money"][ConfigurationMedicMod.Language]) return end
caller:addMoney( -price )
local ent = ents.Create("drug_medicmod")
ent:SetPos(caller:GetPos() + caller:GetAngles():Forward() * 30 + caller:GetAngles():Up() * 20)
ent:Spawn()
ent:SetDrug(key)
if CPPI then
ent:CPPISetOwner(caller)
end
undo.Create( ConfigurationMedicMod.Sentences["Drugs"][ConfigurationMedicMod.Language] )
undo.AddEntity( ent )
undo.SetPlayer( caller )
undo.Finish()
ent.DrugSpawner = caller
caller.DrugsSpawned = spawneddrugs + 1 or 1
elseif class == "drug_medicmod_s" and spawneddrugs >= ConfigurationMedicMod.MaxDrugsSpawnedWithTheShop then
caller:MedicNotif(ConfigurationMedicMod.Sentences["You've reached the limit of"][ConfigurationMedicMod.Language].." "..ConfigurationMedicMod.Sentences["Drugs"][ConfigurationMedicMod.Language])
elseif key == "entity" and ConfigurationMedicMod.MedicShopEntities[class] and (spawnedEnts[class] or 0) < ConfigurationMedicMod.MedicShopEntities[class].max then
local cfg = ConfigurationMedicMod.MedicShopEntities[class]
if caller:getDarkRPVar("money") < cfg.price then caller:MedicNotif(ConfigurationMedicMod.Sentences["You don't have enough money"][ConfigurationMedicMod.Language]) return end
caller:addMoney( -cfg.price )
local ent = ents.Create(class)
ent:SetPos(caller:GetPos() + caller:GetAngles():Forward() * 30 + caller:GetAngles():Up() * 20 )
ent:Spawn()
if CPPI then
ent:CPPISetOwner(caller)
end
undo.Create( (cfg.name or "Medic mod entity") )
undo.AddEntity( ent )
undo.SetPlayer( caller )
undo.Finish()
caller.spawnedEntsMedicMod = caller.spawnedEntsMedicMod or {}
caller.spawnedEntsMedicMod[class] = caller.spawnedEntsMedicMod[class] or 0
caller.spawnedEntsMedicMod[class] = caller.spawnedEntsMedicMod[class] + 1
elseif key == "entity" and ConfigurationMedicMod.MedicShopEntities[class] and (spawnedEnts[class] or 0) >= ConfigurationMedicMod.MedicShopEntities[class].max then
caller:MedicNotif(ConfigurationMedicMod.Sentences["You've reached the limit of"][ConfigurationMedicMod.Language].." "..ConfigurationMedicMod.MedicShopEntities[class].name)
elseif key == "weapon" and ConfigurationMedicMod.MedicShopWeapons[class] then
if caller:HasWeapon( class ) then caller:MedicNotif(ConfigurationMedicMod.Sentences["You already carry this element on you"][ConfigurationMedicMod.Language]) return end
local cfg = ConfigurationMedicMod.MedicShopWeapons[class]
if caller:getDarkRPVar("money") < cfg.price then caller:MedicNotif(ConfigurationMedicMod.Sentences["You don't have enough money"][ConfigurationMedicMod.Language]) return end
caller:addMoney( -cfg.price )
caller:Give(class)
end
end)

View File

@@ -0,0 +1,35 @@
-- local meta = FindMetaTable( "Player" )
-- function meta:MedicNotif( msg, time )
-- local ply = self
-- if not IsValid( ply ) or not ply:IsPlayer() then return end
-- msg = msg or ""
-- time = time or 5
-- net.Start("MedicMod.NotifiyPlayer")
-- net.WriteString( msg )
-- net.WriteInt( time, 32 )
-- net.Send( ply )
-- end
local meta = FindMetaTable( "Player" )
util.AddNetworkString("MedicMod:NotifyPlayer")
function meta:MedicNotif( msg, time )
local ply = self
if not IsValid( ply ) or not ply:IsPlayer() then return end
msg = msg or ""
time = time or 5
net.Start("MedicMod:NotifyPlayer")
net.WriteString( msg )
net.WriteInt( time, 32 )
net.Send( ply )
end

View File

@@ -0,0 +1,303 @@
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Base Configuration
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
ConfigurationMedicMod.AddonName = "MedicMOD"
-- if set to false, the player would have to press E on the terminal to open the buying menu.
ConfigurationMedicMod.Terminal3D2D = true
-- Percentage of chance that the shock of the defibrillator works ( Default : 50 )
ConfigurationMedicMod.DefibrillatorShockChance = 50
ConfigurationMedicMod.MorphineEffectTime = 10
ConfigurationMedicMod.MoneyUnit = "$"
ConfigurationMedicMod.MedicCommand = "medic"
ConfigurationMedicMod.MaxTestTubesSpawnedWithTheShop = 4
ConfigurationMedicMod.MaxDrugsSpawnedWithTheShop = 3
ConfigurationMedicMod.ScanRadioTime = 5
ConfigurationMedicMod.HealedOnChangingJob = true
-- Only medic can use the button to take a stretcher in a vehicle?
ConfigurationMedicMod.OnlyMedicCanUseVehicleButton = true
ConfigurationMedicMod.SurgicalOperationTime = 15
ConfigurationMedicMod.HealthUnitPrice = 1
ConfigurationMedicMod.FractureRepairPrice = 50
ConfigurationMedicMod.ForceRespawn = false
-- Time that the player will have to wait to respawn if there is no medics connected
ConfigurationMedicMod.TimeBeforeRespawnIfNoConnectedMedics = 30
-- Time that the player will have to wait to respawn if there is medics connected
ConfigurationMedicMod.TimeBeforeRespawn = 60
-- Time that the player will have to wait to respawn if someone has stabilized his state
ConfigurationMedicMod.TimeBeforeRespawnIfStable = 360
ConfigurationMedicMod.DamagePerSecsDuringBleeding = 1
ConfigurationMedicMod.DamagePerSecsDuringPoisoned = 0.25
-- if the player get X damage on his leg or his arm, then he'll have a fracture
ConfigurationMedicMod.MinimumDamageToGetFractures = 20
ConfigurationMedicMod.MinimumDamageToGetBleeding = 20
ConfigurationMedicMod.CanGetFractures = true
-- if a player get a damage in his hands, I will not be able to switch weapon
ConfigurationMedicMod.CanBreakArms = true
ConfigurationMedicMod.CanGetBleeding = true
ConfigurationMedicMod.CanGetPoisoned = true
-- now set to false by defaut, because it caused some crashs.
ConfigurationMedicMod.DecalsBleeding = false
ConfigurationMedicMod.TimeToQuickAnalyse = 5
-- If the player can do CPR to another player
ConfigurationMedicMod.CanCPR = true
-- CPR Key, list of keys can be find here : http://wiki.garrysmod.com/page/Enums/BUTTON_CODE
ConfigurationMedicMod.CPRKey = KEY_R
ConfigurationMedicMod.FracturePlayerSpeed = 100
-- if !reviveme can be used
ConfigurationMedicMod.CanUseReviveMeCommand = true
ConfigurationMedicMod.Vehicles["models/perrynsvehicles/ford_f550_ambulance/ford_f550_ambulance.mdl"] = {
buttonPos = Vector(-40.929615,-139.366989,60.128445),
buttonAngle = Angle(0,0,90),
stretcherPos = Vector(0,-80,40),
stretcherAngle = Angle(0,0,0),
drawStretcher = false,
backPos = Vector(0,-170,50)
}
ConfigurationMedicMod.Vehicles["models/perrynsvehicles/2015_mercedes_nhs_ambulance/2015_mercedes_nhs_ambulance.mdl"] = {
buttonPos = Vector(40,-158,70),
buttonAngle = Angle(90,-90,0),
stretcherPos = Vector(13,-95,45),
stretcherAngle = Angle(0,0,0),
drawStretcher = false,
backPos = Vector(0,-170,50)
}
-- list of entities that the medic can buy with his command
ConfigurationMedicMod.MedicShopEntities = {
["firstaidkit_medicmod"] = {
name = "First aid kit",
price = 100,
model = "models/medicmod/firstaidkit/firstaidkit.mdl",
max = 1,
},
["beaker_medicmod"] = {
name = "Empty beaker",
price = 20,
model = "models/medicmod/beaker/beaker.mdl",
max = 1,
},
["bloodbag_medicmod"] = {
name = "Blood bag",
price = 20,
model = "models/medicmod/bloodbag/bloodbag.mdl",
max = 1,
},
["drip_medicmod"] = {
name = "Drip",
price = 120,
model = "models/medicmod/medical_stand/medical_stand.mdl",
max = 1,
},
["drug_medicmod"] = {
name = "Emtpy drug jar",
price = 10,
model = "models/medicmod/drug/drug.mdl",
max = 1,
},
}-- list of weapons that the medic can buy with his command
ConfigurationMedicMod.MedicShopWeapons = {
["syringe_antidote"] = {
name = "Antidote syringe",
price = 50,
model = "models/medicmod/syringe/w_syringe.mdl",
},
["bandage"] = {
name = "Bandage",
price = 20,
model = "models/medicmod/bandage/w_bandage.mdl",
},
["defibrillator"] = {
name = "Defibrillator",
price = 200,
model = "models/medicmod/defib/w_defib.mdl",
},
["syringe_morphine"] = {
name = "Morphine syringe",
price = 150,
model = "models/medicmod/syringe/w_syringe.mdl",
},
["syringe_poison"] = {
name = "Poison syringe",
price = 300,
model = "models/medicmod/syringe/w_syringe.mdl",
},
}
timer.Simple(0, function() -- don't touch this
ConfigurationMedicMod.MedicTeams = {
TEAM_MEDIC,
TEAM_PARAMEDIC,
}
ConfigurationMedicMod.TeamsCantGetFracture = {
}
ConfigurationMedicMod.TeamsCantGetBleeding = {
}
ConfigurationMedicMod.TeamsCantGetPoisoned = {
}
ConfigurationMedicMod.TeamsCantPracticeCPR = {
}
ConfigurationMedicMod.TeamsCantReceiveCPR = {
}
end) -- don't touch this
local lang = ConfigurationMedicMod.Language
local sentences = ConfigurationMedicMod.Sentences
local function AddReagent( name, price, color ) ConfigurationMedicMod.AddReagent( name, price, color ) end
local function AddDrug( name, price, ing1, ing2, ing3, func ) ConfigurationMedicMod.AddDrug( name, price, ing1, ing2, ing3, func ) end
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Add reagents (ingredients) for drugs
-- AddReagent( name, price, color )
AddReagent("Aminophenol", 20 ,Color(255,0,0))
AddReagent("Water", 20, Color(64, 164, 223) )
AddReagent("Ethanoic anhydride", 20,Color(255,255,0))
AddReagent("Potassium iodide", 20, Color(255,255,255))
AddReagent("Ethanol", 20,Color(255,255,255,150))
AddReagent("Sulfuric acid", 20,Color(0,255,0))
AddReagent("Calcium (left arm)", 20,Color(120,140,126))
AddReagent("Calcium (right arm)", 20,Color(120,140,126))
AddReagent("Calcium (left leg)", 20,Color(120,140,126))
AddReagent("Calcium (right leg)", 20,Color(120,140,126))
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Add drugs
-- AddDrug( name, price, reagent1, reagent2, reagent3 , function(ply) end )
-- if there is no reagent 2 or 3 then replace them by nil
AddDrug("Tylenol", 150, "Aminophenol", "Water", "Ethanoic anhydride", function(ply) ply:MedicNotif(sentences["You have been healed"][lang]) ply:SetHealth(ply:GetMaxHealth()) end )
AddDrug("Antidote", 150, "Potassium iodide", nil, nil, function(ply) ply:SetPoisoned( false ) ply:MedicNotif( sentences["You have stopped your poisoning"][lang], 5 ) end)
AddDrug("Morphine", 150, "Water","Ethanol","Sulfuric acid", function(ply) ply:SetMorphine( true ) ply:MedicNotif( sentences["You injected some morphine"][lang], 5 ) end)
AddDrug("Medicine (Left arm)", 150,"Calcium (left arm)", nil, nil, function(ply) ply:SetFracture( false, HITGROUP_LEFTARM) end)
AddDrug("Drug (Right arm)", 150, "Calcium (right arm)", nil, nil, function(ply) ply:SetFracture( false, HITGROUP_RIGHTARM) end )
AddDrug("Drug (Left leg)",150,"Calcium (left leg)", nil, nil, function(ply) ply:SetFracture( false, HITGROUP_LEFTLEG) end )
AddDrug("Drug (Right leg)", 150, "Calcium (right leg)", nil, nil, function(ply) ply:SetFracture( false, HITGROUP_RIGHTLEG) end )
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- List of entities that can be bought with the terminal
ConfigurationMedicMod.Entities[1] = {
name = sentences["Bandage"][lang],
ent = "bandage",
price = 75,
mdl = "models/medicmod/bandage/bandage.mdl",
func = function(ply, ent, price)
if ply:HasWeapon( ent ) then
ply:MedicNotif(sentences["You already carry this element on you"][lang])
return
end
ply:addMoney( -price )
ply:Give(ent)
end
}
ConfigurationMedicMod.Entities[2] = {
name = sentences["Morphine"][lang],
ent = "syringe_morphine",
price = 100,
mdl = "models/medicmod/syringe/w_syringe.mdl",
func = function(ply, ent, price)
if ply:HasWeapon( ent ) then
ply:MedicNotif(sentences["You already carry this element on you"][lang])
return
end
ply:addMoney( -price )
ply:Give(ent)
end
}
ConfigurationMedicMod.Entities[3] = {
name = sentences["Antidote"][lang],
ent = "syringe_antidote",
price = 50,
mdl = "models/medicmod/syringe/w_syringe.mdl",
func = function(ply, ent, price)
if ply:HasWeapon( ent ) then
ply:MedicNotif(sentences["You already carry this element on you"][lang])
return
end
ply:addMoney( -price )
ply:Give(ent)
end
}
ConfigurationMedicMod.Entities[4] = {
name = sentences["First Aid Kit"][lang],
ent = "first_aid_kit",
price = 400,
mdl = "models/medicmod/firstaidkit/firstaidkit.mdl",
func = function(ply, ent, price)
if ply:HasWeapon( ent ) then
ply:MedicNotif(sentences["You already carry a medical kit on you"][lang])
return
end
ply:addMoney( -price )
ply:Give(ent)
local weap = ply:GetWeapon(ent)
weap:SetBandage( 3 )
weap:SetAntidote( 1 )
weap:SetMorphine( 2 )
end
}
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
ConfigurationMedicMod.DamagePoisoned[DMG_PARALYZE]=true
ConfigurationMedicMod.DamagePoisoned[DMG_POISON]=true
ConfigurationMedicMod.DamagePoisoned[DMG_ACID]=true
ConfigurationMedicMod.DamagePoisoned[DMG_RADIATION]=true
ConfigurationMedicMod.DamageBleeding[DMG_BULLET]=true
ConfigurationMedicMod.DamageBleeding[DMG_CRUSH]=true
ConfigurationMedicMod.DamageBleeding[DMG_SLASH]=true
ConfigurationMedicMod.DamageBleeding[DMG_VEHICLE]=true
ConfigurationMedicMod.DamageBleeding[DMG_BLAST]=true
ConfigurationMedicMod.DamageBleeding[DMG_CLUB]=true
ConfigurationMedicMod.DamageBleeding[DMG_AIRBOAT]=true
ConfigurationMedicMod.DamageBleeding[DMG_BLAST_SURFACE]=true
ConfigurationMedicMod.DamageBleeding[DMG_BUCKSHOT]=true
ConfigurationMedicMod.DamageBleeding[DMG_PHYSGUN]=true
ConfigurationMedicMod.DamageBleeding[DMG_FALL]=true
ConfigurationMedicMod.DamageBleeding[DMG_MEDICMODBLEEDING]=true
ConfigurationMedicMod.DamageBurn[DMG_BURN]=true
ConfigurationMedicMod.DamageBurn[DMG_SLOWBURN]=true
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------

View File

@@ -0,0 +1,46 @@
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
local lang = ConfigurationMedicMod.Language
local sentences = ConfigurationMedicMod.Sentences
-- add entities to the medic job
timer.Simple(0, function()
DarkRP.createEntity("Beaker", {
ent = "beaker_medicmod",
model = "models/medicmod/beaker/beaker.mdl",
price = 30,
max = 2,
cmd = "buybeaker",
allowed = ConfigurationMedicMod.MedicTeams,
})
DarkRP.createEntity("Drug pot", {
ent = "drug_medicmod",
model = "models/medicmod/drug/drug.mdl",
price = 10,
max = 2,
cmd = "buydrugpot",
allowed = ConfigurationMedicMod.MedicTeams,
})
DarkRP.createEntity("Blood bag", {
ent = "bloodbag_medicmod",
model = "models/medicmod/bloodbag/bloodbag.mdl",
price = 10,
max = 2,
cmd = "buybloodbag",
allowed = ConfigurationMedicMod.MedicTeams,
})
DarkRP.createEntity("Drip", {
ent = "drip_medicmod",
model = "models/medicmod/medical_stand/medical_stand.mdl",
price = 100,
max = 2,
cmd = "buydrip",
allowed = ConfigurationMedicMod.MedicTeams,
})
end)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
local meta = FindMetaTable( "Player" )
function meta:IsBleeding()
return self:GetNWBool("Bleeding") or false
end
function meta:GetHeartAttack()
return self:GetNWBool("HeartAttack") or false
end
function meta:IsPoisoned()
return self:GetNWBool("Poisoned") or false
end
function meta:GetMedicAnimation()
return self:GetNWInt("MedicActivity") or 0
end
function meta:IsMorphine()
return self:GetNWBool("Morphine") or false
end
function meta:IsFractured()
return self:GetNWBool("Fracture") or false
end
function meta:Stable()
if self:IsPoisoned() or self:GetHeartAttack() or self:IsBleeding() then
return false
else
return true
end
end
local ent = FindMetaTable( "Entity" )
function ent:IsDeathRagdoll()
return self:GetNWBool("IsDeathRagdoll") or false
end

View File

@@ -0,0 +1,114 @@
local sentences =ConfigurationMedicMod.Sentences
local lang = ConfigurationMedicMod.Language
-- Play animations
hook.Add("CalcMainActivity", "CalcMainActivity.MedicMod", function(ply, vel)
if ply:GetMedicAnimation() == 1 then
local seqid = ply:LookupSequence( "medic_custom1" )
ply:SetSequence( seqid )
return -1, seqid
end
if ply:GetMedicAnimation() == 2 then
-- stop the animation if the ragdoll isn't near the player
if not ply:GetEyeTrace().Entity:IsDeathRagdoll() or ply:GetEyeTrace().Entity:GetPos():Distance(ply:GetPos()) > 100 then
if SERVER then
if IsValid( ply.RagdollHeartMassage ) && IsValid( ply.RagdollHeartMassage:GetOwner() ) then
ply.RagdollHeartMassage:GetOwner().NextSpawnTime = CurTime() + ply.RagdollHeartMassage:GetOwner().AddToSpawnTime
ply.RagdollHeartMassage.IsHeartMassage = false
net.Start("MedicMod.Respawn")
net.WriteInt(ply.RagdollHeartMassage:GetOwner().NextSpawnTime,32)
net.Send(ply)
end
ply:StripWeapon("heart_massage")
end
if SERVER then StopMedicAnimation( ply ) end
return
end
local seqid = ply:LookupSequence( "medic_custom2" )
ply:SetSequence( seqid )
return -1, seqid
end
end)
hook.Add("PlayerButtonUp", "PlayerButtonUp.MedicMod", function( ply, but )
if table.HasValue( ConfigurationMedicMod.TeamsCantPracticeCPR, ply:Team() ) then return end
if but != ConfigurationMedicMod.CPRKey or not ConfigurationMedicMod.CanCPR then return end
if ply.blocAnim && ply.blocAnim >= CurTime() then return end
-- if the player press the configured key, then stop his animation
if ply:GetMedicAnimation() != 0 then
if SERVER then
-- add condition pour si le mec n'a plus d'arrêt cardiaque
if IsValid( ply.RagdollHeartMassage ) && IsValid( ply.RagdollHeartMassage:GetOwner() ) then
ply.RagdollHeartMassage:GetOwner().NextSpawnTime = CurTime() + ply.RagdollHeartMassage:GetOwner().AddToSpawnTime
ply.RagdollHeartMassage.IsHeartMassage = false
net.Start("MedicMod.Respawn")
net.WriteInt(ply.RagdollHeartMassage:GetOwner().NextSpawnTime,32)
net.Send(ply.RagdollHeartMassage:GetOwner())
end
ply:StripWeapon("heart_massage")
end
ply.blocAnim = CurTime() + 2
if SERVER then StopMedicAnimation( ply ) end
return
end
local trace = ply:GetEyeTrace()
local ent = trace.Entity
if not IsValid(ent) then return end
if ent.IsHeartMassage then return end
if not ent:IsDeathRagdoll() or ent:GetClass() == "prop_physics" or trace.HitPos:Distance(ply:GetPos()) > 100 then return end
if table.HasValue( ConfigurationMedicMod.TeamsCantReceiveCPR, ent:GetOwner():Team() ) then return end
if ent:GetOwner().NextSpawnTime == -1 then return end
ply.RagdollHeartMassage = ent
ent.IsHeartMassage = true
if SERVER then StartMedicAnimation( ply, 1 ) end
ply.blocAnim = CurTime() + 5
timer.Simple(2.7, function()
if SERVER then
ply:Give("heart_massage")
ply:SelectWeapon("heart_massage")
ply:MedicNotif( sentences["You are starting CPR"][lang], 10)
ent:GetOwner():MedicNotif( sentences["Someone is giving you CPR"][lang], 10)
end
if SERVER then
StopMedicAnimation( ply )
StartMedicAnimation( ply, 2 )
end
end)
if SERVER then
if not ent:GetOwner():GetHeartAttack() then ent:GetOwner().AddToSpawnTime = 0 return end
if not ent:GetOwner():IsPoisoned() and not ent:GetOwner():IsBleeding() then
ent:GetOwner().AddToSpawnTime = ent:GetOwner().NextSpawnTime - CurTime()
ent:GetOwner().NextSpawnTime = -1
net.Start("MedicMod.Respawn")
net.WriteInt(-1,32)
net.Send(ent:GetOwner())
else
ent:GetOwner().AddToSpawnTime = 0
end
end
end)