add sborka
This commit is contained in:
373
garrysmod/addons/molotok/lua/entities/sent_construction.lua
Normal file
373
garrysmod/addons/molotok/lua/entities/sent_construction.lua
Normal file
@@ -0,0 +1,373 @@
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.PrintName = "Construction"
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_gmodentity"
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminOnly = true
|
||||
ENT.DoNotDuplicate = false
|
||||
ENT._Seen = false
|
||||
ENT._Lerp = 0
|
||||
ENT._Ler2 = 0
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Int", 0, "State")
|
||||
self:NetworkVar("Float", 0, "Progress")
|
||||
self:NetworkVar("String", 0, "Nick")
|
||||
self:NetworkVar("Entity", 0, "Owned")
|
||||
self:NetworkVar("Entity", 1, "Player")
|
||||
|
||||
if SERVER then
|
||||
self:NetworkVarNotify("Progress", function(self, name, old, new)
|
||||
if new >= 99.9 then
|
||||
if self:GetState() == 2 then return end
|
||||
self:SetState(2)
|
||||
|
||||
if self.EntToBuild == "prop_physics" then
|
||||
self.buildEnt = ents.Create("constructor_prop")
|
||||
self.buildEnt:SetPos(self:GetPos() + vector_up*0.5)
|
||||
self.buildEnt:SetAngles(self:GetAngles())
|
||||
|
||||
if self.EntModel then
|
||||
self.buildEnt:SetModel(self.EntModel)
|
||||
self.buildEnt.Model = self.EntModel
|
||||
else
|
||||
self.buildEnt:SetModel(self:GetModel())
|
||||
end
|
||||
|
||||
self.buildEnt.InitialHealth = self.EntHealth or 10000
|
||||
self.buildEnt.PropName = self:GetNick() or "Constructor Prop"
|
||||
|
||||
self.buildEnt:Spawn()
|
||||
self.buildEnt:Activate()
|
||||
self.buildEnt:SetNWEntity("SpikeOwner", self:GetPlayer())
|
||||
self.buildEnt.BuilderCost = self.EntToBuildCost or 10
|
||||
|
||||
local phys = self.buildEnt:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
|
||||
if self.EntToBuild == "sw_sania" then
|
||||
timer.Simple(0, function()
|
||||
if not IsValid(self.buildEnt) then return end
|
||||
|
||||
local nearest
|
||||
local dist = 200
|
||||
|
||||
for _, veh in ipairs(ents.FindInSphere(self:GetPos(), 200)) do
|
||||
if veh.LVS then
|
||||
local d = veh:GetPos():Distance(self:GetPos())
|
||||
if d < dist then
|
||||
dist = d
|
||||
nearest = veh
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if IsValid(nearest) then
|
||||
local physTarget = nearest:GetBase() or nearest
|
||||
|
||||
self.buildEnt:SetPos(nearest:GetPos() + Vector(0,0,60))
|
||||
self.buildEnt:SetAngles(nearest:GetAngles())
|
||||
|
||||
constraint.Weld(self.buildEnt, physTarget, 0, 0, 0, true)
|
||||
|
||||
print("[REB] РЭБ приварена к LVS:", nearest)
|
||||
else
|
||||
print("[REB] LVS техника не найдена рядом")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
undo.ReplaceEntity(self, self.buildEnt)
|
||||
cleanup.ReplaceEntity(self, self.buildEnt)
|
||||
|
||||
sound.Play("weapons/building.wav", self:GetPos() + vector_up*16, 80, 120)
|
||||
self:Remove()
|
||||
return
|
||||
else
|
||||
self.buildEnt = ents.Create(self.EntToBuild)
|
||||
|
||||
if not IsValid(self.buildEnt) then
|
||||
return
|
||||
end
|
||||
|
||||
self.buildEnt:SetPos(self:GetPos() + vector_up*0.5)
|
||||
self.buildEnt:SetAngles(self:GetAngles())
|
||||
|
||||
self.buildEnt:SetKeyValue("Modification", 1)
|
||||
|
||||
if self:GetNick() == "Rebel Turret" then
|
||||
self.buildEnt:SetKeyValue("spawnflags", 512)
|
||||
self.buildEnt:SetSaveValue("m_bHackedByAlyx", true)
|
||||
end
|
||||
|
||||
self.buildEnt:SetSaveValue("m_bPlacedByPlayer", true)
|
||||
self.buildEnt:SetSaveValue("m_Efficiency", 2)
|
||||
self.buildEnt:SetSaveValue("m_CurrentWeaponProficiency", 100)
|
||||
|
||||
self.buildEnt:Spawn()
|
||||
self.buildEnt:Activate()
|
||||
self.buildEnt.BuilderCost = self.EntToBuildCost or 10
|
||||
|
||||
|
||||
local owner = self:GetOwned() or self:GetOwner()
|
||||
self.buildEnt:SetNWEntity("SpikeOwner", owner)
|
||||
|
||||
if self.buildEnt:GetClass():find("sent_ranged_healer") then
|
||||
self.buildEnt:SetHealEverything(false)
|
||||
self.buildEnt:SetHealRadius(256)
|
||||
self.buildEnt:SetHealTeam(1001)
|
||||
if owner and owner:IsPlayer() then
|
||||
self.buildEnt:SetPlayer(owner)
|
||||
end
|
||||
self.buildEnt:SetReplenishArmor(false)
|
||||
elseif self.buildEnt:GetClass():find("barricade") then
|
||||
local phys = self.buildEnt:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
self.buildEnt:SetPos(self:GetPos() + vector_up*-5)
|
||||
elseif self.buildEnt:GetClass():find("item_") then
|
||||
self.buildEnt:PhysicsInit(SOLID_VPHYSICS)
|
||||
if IsValid(self.MyWeldedEnt) then
|
||||
constraint.Weld(self.buildEnt, self.MyWeldedEnt, 0, 0, 0, 0, true)
|
||||
else
|
||||
local phys = self.buildEnt:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
end
|
||||
elseif self.buildEnt:GetClass() == "bouncingmortar" or
|
||||
self.buildEnt:GetClass() == "ent_trappopeller_engine" then
|
||||
local phys = self.buildEnt:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
self.buildEnt:SetAngles(angle_zero)
|
||||
elseif self.buildEnt:GetClass() == "npc_turret_floor" then
|
||||
self.buildEnt:SetNWBool("RebSentri", true)
|
||||
if self:GetNick() == "Rebel Turret" then
|
||||
local v = self.buildEnt
|
||||
v.FriendsWithAllPlayerAllies = true
|
||||
v.PlayerFriendly = true
|
||||
v.VJ_NPC_Class = {"CLASS_REBEL"}
|
||||
v.DisableMakingSelfEnemyToNPCs = true
|
||||
|
||||
if math.random() < 0.33 then
|
||||
v:SetSubMaterial(0, "models/combine_turrets/floor_turret/floor_turret_citizen")
|
||||
v:SetMaterial("models/combine_turrets/floor_turret/floor_turret_citizen")
|
||||
elseif math.random() > 0.33 then
|
||||
v:SetSubMaterial(0, "models/combine_turrets/floor_turret/floor_turret_citizen2")
|
||||
v:SetMaterial("models/combine_turrets/floor_turret/floor_turret_citizen2")
|
||||
else
|
||||
v:SetSubMaterial(0, "models/combine_turrets/floor_turret/floor_turret_citizen4")
|
||||
v:SetMaterial("models/combine_turrets/floor_turret/floor_turret_citizen4")
|
||||
end
|
||||
end
|
||||
elseif self.buildEnt:GetClass() == "combine_mine" then
|
||||
local v = self.buildEnt
|
||||
if math.random() < 0.33 then
|
||||
v:SetSubMaterial(0, "Models/Combine_Mine/combine_mine_citizen")
|
||||
v:SetMaterial("Models/Combine_Mine/combine_mine_citizen")
|
||||
elseif math.random() > 0.33 then
|
||||
v:SetSubMaterial(0, "Models/Combine_Mine/combine_mine_citizen"..math.random(2,3))
|
||||
v:SetMaterial("Models/Combine_Mine/combine_mine_citizen"..math.random(2,3))
|
||||
end
|
||||
timer.Simple(1, function()
|
||||
if IsValid(v) then
|
||||
v:StopSound("npc/roller/mine/combine_mine_active_loop1.wav")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
undo.ReplaceEntity(self, self.buildEnt)
|
||||
cleanup.ReplaceEntity(self, self.buildEnt)
|
||||
|
||||
sound.Play("weapons/building.wav", self:GetPos() + vector_up*16, 80, 120)
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
else
|
||||
self:SetColor(Color(255, 255, 255, math.Clamp(new/100*255, 32, 192)))
|
||||
end
|
||||
end)
|
||||
|
||||
self:NetworkVarNotify("Owned", function(self, name, old, new)
|
||||
if old == new then return end
|
||||
self.Owner = new
|
||||
self:SetOwner(new)
|
||||
if NADMOD then
|
||||
NADMOD.PlayerMakePropOwner(new, self)
|
||||
end
|
||||
end)
|
||||
|
||||
self:NetworkVarNotify("Player", function(self, name, old, new)
|
||||
if old == new then return end
|
||||
self._Player = new
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:GetPlayer()
|
||||
if SERVER then
|
||||
return self._Player or self:GetVar("Player") or self:GetOwner()
|
||||
else
|
||||
return self:GetVar("Player") or self:GetOwner()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SetPlayer(ply)
|
||||
if not SERVER then return end
|
||||
self._Player = ply
|
||||
self:SetVar("Player", ply)
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
if CLIENT then return end
|
||||
|
||||
if self.EntModel then
|
||||
self:SetModel(self.EntModel)
|
||||
else
|
||||
self:SetModel("models/props_junk/wood_crate001a.mdl")
|
||||
end
|
||||
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
self:DrawShadow(false)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid(phys) then
|
||||
phys:Wake()
|
||||
end
|
||||
|
||||
self:SetProgress(0)
|
||||
self:SetState(0)
|
||||
self:SetNick("")
|
||||
end
|
||||
|
||||
function ENT:Use(ply)
|
||||
if ply:IsPlayer() then
|
||||
if self:IsPlayerHolding() then return end
|
||||
ply:PickupObject(self)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage( damage )
|
||||
self:TakePhysicsDamage(damage)
|
||||
end
|
||||
|
||||
function ENT:PhysicsCollide(data, phys)
|
||||
if data.DeltaTime > 0.2 then
|
||||
if data.Speed > 250 then
|
||||
self:EmitSound("physics/metal/metal_box_impact_hard" .. math.random(1, 3) .. ".wav", 75, math.random(90,110), 0.5)
|
||||
else
|
||||
self:EmitSound("physics/metal/metal_box_impact_soft" .. math.random(1, 3) .. ".wav", 75, math.random(90,110), 0.2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add( "GetPreferredCarryAngles", "BuilderCarryAngs", function( ent )
|
||||
if ent:GetNWBool("RebSentri") then
|
||||
return Angle( -10, 0, 0 )
|
||||
end
|
||||
end)
|
||||
|
||||
if SERVER then return end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if self:GetState() > 0 then
|
||||
local ed = EffectData()
|
||||
ed:SetOrigin(self:GetPos())
|
||||
ed:SetEntity(self)
|
||||
util.Effect( "entity_remove", ed, true, true )
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
if self._Seen != self:BeingLookedAtByLocalPlayer() then
|
||||
self._Seen = self:BeingLookedAtByLocalPlayer() self._Lerp = SysTime() +0.2
|
||||
end
|
||||
self._Ler2 = Lerp( 0.1, self._Ler2, self:GetProgress() )
|
||||
end
|
||||
|
||||
local glow = Material( "models/wireframe" )
|
||||
local Mat = Material( "particle/particle_ring_wave_addnofog" )
|
||||
|
||||
function ENT:Draw()
|
||||
self:DrawModel( )
|
||||
|
||||
render.CullMode(MATERIAL_CULLMODE_CW)
|
||||
self.DrawModel( self )
|
||||
render.CullMode(MATERIAL_CULLMODE_CCW)
|
||||
|
||||
if self:GetState() == 0 then
|
||||
render.SuppressEngineLighting( true )
|
||||
render.SetBlend( 0.25 ) render.MaterialOverride( glow )
|
||||
render.SetColorModulation( 1, 1, 0 )
|
||||
self:DrawModel()
|
||||
render.SetBlend( 1 ) render.MaterialOverride()
|
||||
render.SetColorModulation( 1, 1, 1 )
|
||||
render.SuppressEngineLighting( false )
|
||||
else
|
||||
local pro = math.Clamp( 1 -self:GetProgress()/100, 0, 1 )
|
||||
render.SuppressEngineLighting( true )
|
||||
render.SetBlend( pro/4 ) render.MaterialOverride( glow )
|
||||
render.SetColorModulation( 1, 1, 1 )
|
||||
self:DrawModel()
|
||||
render.SetBlend( 1 ) render.MaterialOverride()
|
||||
render.SetColorModulation( 1, 1, 1 )
|
||||
render.SuppressEngineLighting( false )
|
||||
end
|
||||
if self._Seen or self._Lerp > SysTime() then
|
||||
local ler = math.Clamp( ( self._Lerp -SysTime() )/0.2, 0, 1 )
|
||||
if self._Seen then ler = 1-ler end
|
||||
cam.Start2D()
|
||||
local pos = self:WorldSpaceCenter():ToScreen()
|
||||
local x, y, radius, seg, per = math.Round( pos.x ), math.Round( pos.y ), ler*40, 360, self._Ler2/100
|
||||
for i=1, 6 do surface.DrawCircle( x, y, radius -7 +i, Color( 0, 0, 0, 192*ler ) ) end
|
||||
per = isnumber( per ) and per or 1
|
||||
local cir = {}
|
||||
table.insert( cir, { x = x, y = y, u = 0.5, v = 0.5 } )
|
||||
for i = 0, seg do
|
||||
if i > math.ceil( seg*per ) then break end
|
||||
local a = math.rad( ( i/seg )*-360 +180 )
|
||||
table.insert( cir, { x = x +math.sin( a )*radius, y = y +math.cos( a )*radius, u = math.sin( a )/2 +0.5, v = math.cos( a )/2 +0.5 } )
|
||||
end
|
||||
local a = math.rad( 0 )
|
||||
surface.SetMaterial( Mat ) surface.SetDrawColor( 255, 200, 25, 255*ler )
|
||||
surface.DrawPoly( cir )
|
||||
draw.TextShadow( {
|
||||
text = math.Clamp( math.Round( self._Ler2 ), 0, 100 ).."%",
|
||||
pos = { x, y },
|
||||
font = "ScrapFont2",
|
||||
xalign = TEXT_ALIGN_CENTER,
|
||||
yalign = TEXT_ALIGN_CENTER,
|
||||
color = Color( 255, 200, 25, ler*255 )
|
||||
}, 1, ler*255 )
|
||||
draw.TextShadow( {
|
||||
text = self:GetNick(),
|
||||
pos = { x, y -ler*52 },
|
||||
font = "TargetID",
|
||||
xalign = TEXT_ALIGN_CENTER,
|
||||
yalign = TEXT_ALIGN_CENTER,
|
||||
color = Color( 255, 200, 25, ler*255 )
|
||||
}, 1, ler*255 )
|
||||
if IsValid( self:GetOwned() ) then
|
||||
draw.TextShadow( {
|
||||
text = "("..self:GetOwned():Nick()..")",
|
||||
pos = { x, y +ler*52 },
|
||||
font = "TargetIDSmall",
|
||||
xalign = TEXT_ALIGN_CENTER,
|
||||
yalign = TEXT_ALIGN_CENTER,
|
||||
color = Color( 255, 200, 25, ler*255 )
|
||||
}, 1, ler*255 )
|
||||
end
|
||||
cam.End2D()
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user