diff --git a/README.md b/README.md index f8432de2..91c271ac 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,14 @@ A pack of content and entity classes to add cars, motorcycles, planes, helicopte | `glide_projectile_launcher_max_radius` `` | Maximum radius from explosions created by Glide Projectile Launchers | `glide_projectile_launcher_max_damage` `` | Maximum damage dealt by explosions from Glide Projectile Launchers +### Flare Launcher tool limits + +| Command | Description | +| ------- | ----------- | +| `glide_flare_launcher_min_delay` `` | Minimum delay allowed for Glide Flare Launchers | +| `glide_flare_launcher_max_force` `` | Maximum launch force allowed for Glide Flare Launchers | + + ### Repair Ray tool limits | Command | Description diff --git a/lua/autorun/sh_glide.lua b/lua/autorun/sh_glide.lua index 0ea0ea25..fbde1557 100644 --- a/lua/autorun/sh_glide.lua +++ b/lua/autorun/sh_glide.lua @@ -202,6 +202,7 @@ cleanup.Register( "glide_trailers" ) cleanup.Register( "glide_standalone_turrets" ) cleanup.Register( "glide_missile_launchers" ) cleanup.Register( "glide_projectile_launchers" ) +cleanup.Register( "glide_flare_launchers" ) CreateConVar( "sbox_maxglide_vehicles", "5", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Max. number of Glide vehicles that one player can have", 0 ) CreateConVar( "sbox_maxglide_trailers", "5", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Max. number of Glide trailers that one player can have (separate from sbox_maxglide_vehicles)", 0 ) @@ -229,6 +230,11 @@ CreateConVar( "glide_projectile_launcher_max_lifetime", "10", FCVAR_ARCHIVE + FC CreateConVar( "glide_projectile_launcher_max_radius", "500", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Maximum radius from explosions created by Glide Projectile Launchers.", 10 ) CreateConVar( "glide_projectile_launcher_max_damage", "200", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Maximum damage dealt by explosions from Glide Projectile Launchers.", 1 ) +-- Flare launcher tool convars +CreateConVar( "sbox_maxglide_flare_launchers", "5", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Max. number of Glide Flare Launchers that one player can have", 0 ) +CreateConVar( "glide_flare_launcher_min_delay", "0.1", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Minimum delay allowed for Glide Flare Launchers.", 0.05, 5 ) +CreateConVar( "glide_flare_launcher_max_force", "3000", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Maximum launch force allowed for Glide Flare Launchers.", 100 ) + -- Repair Ray tool convars CreateConVar( "glide_repair_ray_max_capacity", "600", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "Maximum amount of HP that Glide Repair Rays can hold.", 1, 10000 ) CreateConVar( "glide_repair_ray_output_per_second", "50", FCVAR_ARCHIVE + FCVAR_NOTIFY + FCVAR_REPLICATED, "How fast to output HP from the Glide Repair Rays, per second.", 1, 1000 ) diff --git a/lua/entities/glide_flare_launcher.lua b/lua/entities/glide_flare_launcher.lua new file mode 100644 index 00000000..178ddc6b --- /dev/null +++ b/lua/entities/glide_flare_launcher.lua @@ -0,0 +1,145 @@ +AddCSLuaFile() + +ENT.Type = "anim" +ENT.Base = "base_anim" +ENT.PrintName = "Flare Launcher" +ENT.Category = "Glide" + +ENT.Spawnable = false +ENT.AdminOnly = false +ENT.AutomaticFrameAdvance = true + +if not SERVER then return end + +local ENT_VARS = { + ["reloadDelay"] = true, + ["launchForce"] = true +} + +function ENT:OnEntityCopyTableFinish( data ) + Glide.FilterEntityCopyTable( data, nil, ENT_VARS ) +end + +function ENT:PreEntityCopy() + Glide.PreEntityCopy( self ) +end + +function ENT:PostEntityPaste( ply, ent, createdEntities ) + Glide.PostEntityPaste( ply, ent, createdEntities ) + + -- Update parameters in case the limits/console variables + -- are different compared to when this entity was duped. + self:SetReloadDelay( self.reloadDelay ) + self:SetLaunchForce( self.launchForce ) +end + +local function MakeSpawner( ply, data ) + if IsValid( ply ) and not ply:CheckLimit( "glide_flare_launchers" ) then return end + + local ent = ents.Create( data.Class ) + if not IsValid( ent ) then return end + + ent:SetPos( data.Pos ) + ent:SetAngles( data.Angle ) + ent:SetCreator( ply ) + ent:Spawn() + ent:Activate() + + ply:AddCount( "glide_flare_launchers", ent ) + cleanup.Add( ply, "glide_flare_launchers", ent ) + + for k, v in pairs( data ) do + if ENT_VARS[k] then ent[k] = v end + end + + return ent +end + +duplicator.RegisterEntityClass( "glide_flare_launcher", MakeSpawner, "Data" ) + +function ENT:SpawnFunction( ply, tr ) + if tr.Hit then + return MakeSpawner( ply, { + Pos = tr.HitPos, + Angle = Angle(), + Class = self.ClassName + } ) + end +end + +function ENT:Initialize() + self:SetModel( "models/props_junk/PopCan01a.mdl" ) + self:SetSolid( SOLID_VPHYSICS ) + self:SetMoveType( MOVETYPE_VPHYSICS ) + self:PhysicsInit( SOLID_VPHYSICS ) + self:SetCollisionGroup( COLLISION_GROUP_WEAPON ) + self:DrawShadow( false ) + + self.reloadDelay = 0.5 + self.launchForce = 1000 + + self.isFiring = false + self.nextShoot = 0 + + if WireLib then + WireLib.CreateSpecialInputs( self, + { "Fire", "Delay", "Force" }, + { "NORMAL", "NORMAL", "NORMAL" } + ) + end +end + +local CurTime = CurTime +local PlaySoundSet = Glide.PlaySoundSet + +function ENT:Think() + local t = CurTime() + + if self.isFiring and t > self.nextShoot then + self.nextShoot = t + self.reloadDelay + + local dir = self:GetUp() + + local flare = ents.Create( "glide_flare" ) + flare:SetPos( self:GetPos() + dir * 10 ) + flare:SetAngles( dir:Angle() ) + flare:SetOwner( self:GetCreator() ) + flare:Spawn() + + local phys = flare:GetPhysicsObject() + + if IsValid( phys ) then + phys:SetVelocityInstantaneous( dir * self.launchForce ) + end + + Glide.CopyEntityCreator( self, flare ) + PlaySoundSet( "Glide.FlareLaunch", self, 1 ) + end + + self:NextThink( t ) + + return true +end + +local cvarMinDelay = GetConVar( "glide_flare_launcher_min_delay" ) +local cvarMaxForce = GetConVar( "glide_flare_launcher_max_force" ) + +function ENT:SetReloadDelay( delay ) + self.reloadDelay = math.Clamp( delay, cvarMinDelay and cvarMinDelay:GetFloat() or 0.1, 5 ) +end + +function ENT:SetLaunchForce( force ) + self.launchForce = math.Clamp( force, 100, cvarMaxForce and cvarMaxForce:GetFloat() or 3000 ) +end + +function ENT:TriggerInput( name, value ) + if name == "Fire" then + self.isFiring = value > 0 + + elseif name == "Delay" then + self:SetReloadDelay( value ) + + elseif name == "Force" then + self:SetLaunchForce( value ) + end +end \ No newline at end of file diff --git a/lua/weapons/gmod_tool/stools/glide_flare_launcher.lua b/lua/weapons/gmod_tool/stools/glide_flare_launcher.lua new file mode 100644 index 00000000..7351af1c --- /dev/null +++ b/lua/weapons/gmod_tool/stools/glide_flare_launcher.lua @@ -0,0 +1,109 @@ +TOOL.Category = "Glide" +TOOL.Name = "#tool.glide_flare_launcher.name" + +TOOL.Information = { + { name = "left" }, + { name = "right" } +} + +TOOL.ClientConVar = { + delay = 0.5, + force = 1000 +} + +local function IsGlideFlareLauncher( ent ) + return IsValid( ent ) and ent:GetClass() == "glide_flare_launcher" +end + +if SERVER then + function TOOL:Deploy() + Glide.ToolCheckMissingWiremod( self:GetOwner() ) + end + + function TOOL:UpdateFlareLauncher( ent ) + local delay = self:GetClientNumber( "delay" ) + local force = self:GetClientNumber( "force" ) + + ent:SetReloadDelay( delay ) + ent:SetLaunchForce( force ) + end +end + +function TOOL:LeftClick( trace ) + local ent = trace.Entity + + if IsGlideFlareLauncher( ent ) then + if SERVER then + self:UpdateFlareLauncher( ent ) + end + + return true + end + + local ply = self:GetOwner() + if not ply:CheckLimit( "glide_flare_launchers" ) then return false end + + if SERVER then + local normal = trace.HitNormal + local pos = trace.HitPos + normal * 5 + + ent = duplicator.CreateEntityFromTable( ply, { + Class = "glide_flare_launcher", + Pos = pos, + Angle = normal:Angle() + Angle( 90, 0, 0 ) + } ) + + if not IsValid( ent ) then return false end + + undo.Create( self.Name ) + undo.AddEntity( ent ) + undo.SetPlayer( ply ) + undo.Finish() + + self:UpdateFlareLauncher( ent ) + end + + return true +end + +function TOOL:RightClick( trace ) + local ent = trace.Entity + if not IsGlideFlareLauncher( ent ) then return false end + + if SERVER then + local ply = self:GetOwner() + local delay = ent.reloadDelay + local force = ent.launchForce + + ply:ConCommand( "glide_flare_launcher_delay " .. delay ) + ply:ConCommand( "glide_flare_launcher_force " .. force ) + end + + return true +end + +local cvarMinDelay = GetConVar( "glide_flare_launcher_min_delay" ) +local cvarMaxForce = GetConVar( "glide_flare_launcher_max_force" ) + +local conVarsDefault = TOOL:BuildConVarList() + +function TOOL.BuildCPanel( panel ) + panel:Help( "#tool.glide_flare_launcher.desc" ) + panel:ToolPresets( "glide_flare_launcher", conVarsDefault ) + + panel:AddControl( "slider", { + Label = "#tool.glide_flare_launcher.delay", + command = "glide_flare_launcher_delay", + type = "float", + min = cvarMinDelay and cvarMinDelay:GetFloat() or 0.1, + max = 5 + } ) + + panel:AddControl( "slider", { + Label = "#tool.glide_flare_launcher.force", + command = "glide_flare_launcher_force", + type = "float", + min = 100, + max = cvarMaxForce and cvarMaxForce:GetFloat() or 3000 + } ) +end \ No newline at end of file diff --git a/resource/localization/en/glide_vehicles.properties b/resource/localization/en/glide_vehicles.properties index d7d9996f..d2a6dc5a 100644 --- a/resource/localization/en/glide_vehicles.properties +++ b/resource/localization/en/glide_vehicles.properties @@ -391,6 +391,15 @@ tool.glide_bullet_proof_tires.desc=Prevent the tires from deflating tool.glide_bullet_proof_tires.left=Make tires bulletproof tool.glide_bullet_proof_tires.reload=Stop making tires bulletproof +tool.glide_flare_launcher.name=Flare Launcher +tool.glide_flare_launcher.desc=Launches countermeasure flares +tool.glide_flare_launcher.left=Spawn/update flare launcher +tool.glide_flare_launcher.right=Copy settings from another flare launcher +tool.glide_flare_launcher.delay=Reload delay +tool.glide_flare_launcher.force=Launch force + + +SBoxLimit_glide_flare_launcher=You've hit the Glide Flare Launcher limit! SBoxLimit_glide_vehicles=You've hit the Glide vehicle limit! SBoxLimit_glide_trailers=You've hit the Glide trailer limit! SBoxLimit_glide_turret=You've hit the Glide Turret limit! @@ -401,4 +410,5 @@ Cleanup_glide_vehicles=Glide Vehicles Cleanup_glide_trailers=Glide Trailers Cleanup_glide_standalone_turrets=Glide Standalone Turrets Cleanup_glide_missile_launchers=Glide Missile Launchers -Cleanup_glide_projectile_launchers=Glide Projectile Launchers \ No newline at end of file +Cleanup_glide_projectile_launchers=Glide Projectile Launchers +Cleanup_glide_flare_launchers=Glide Flare Launchers \ No newline at end of file diff --git a/resource/localization/pt-br/glide_vehicles.properties b/resource/localization/pt-br/glide_vehicles.properties index 8a113ed0..8ced54bb 100644 --- a/resource/localization/pt-br/glide_vehicles.properties +++ b/resource/localization/pt-br/glide_vehicles.properties @@ -402,4 +402,15 @@ Cleanup_glide_vehicles=Veículos Glide Cleanup_glide_trailers=Reboques Glide Cleanup_glide_standalone_turrets=Glide Armas Cleanup_glide_missile_launchers=Glide Lança-mísseis -Cleanup_glide_projectile_launchers=Glide Lança-projéteis \ No newline at end of file +Cleanup_glide_projectile_launchers=Glide Lança-projéteis + +tool.glide_flare_launcher.name=Lançador de Flare +tool.glide_flare_launcher.desc=Lança chamas de iluminação (contramedidas) +tool.glide_flare_launcher.left=Criar/atualizar lançador de flare +tool.glide_flare_launcher.right=Copiar as configurações de outro lançador de flare +tool.glide_flare_launcher.delay=Atraso de recarga +tool.glide_flare_launcher.force=Força de lançamento + +SBoxLimit_glide_flare_launcher=Você atingiu o limite de Lançadores de Flare do Glide! + +Cleanup_glide_flare_launchers=Glide Lançadores de Flare