Hello!
I've build my first entity and it was very complicated. After hours of scripting there is one problem that I can't solve. I have a screenshot [URL="https://abload.de/img/20170419151917_1p1srz.jpg"]at this link[/URL]. Now my problem:
This weapon creates a laserbeam to it's target. It can shoot only on clear sight to the target. With one of this entity it works fine! But if i spawn more, all of these entitys will attack the one target at the same time accross the map. But every single entity should run for it's self. Every entity have it's own target.
I'm german so my english is maybe not as beautiful as it can be. :buckteeth: Here are my scripts:
cl_init.lua
[CODE]--Binde die Datei ein
include('shared.lua')
--Definiere Basisvariablen
--Laser
local p2 = Vector(0,0,0)
local sbt = false
local beam_alpha = 0
local beam_color = Color(0,0,0,0)
local beam_fadetime = 0
--Empfängt die Laser-Koordinaten und den startbefehl
net.Receive("DrawLaserB",
function()
p2 = net.ReadVector()
end
)
net.Receive("drawbit",
function()
sbt = net.ReadBool()
end
)
--Wird beim Darstellen des Entity ausgeführt (also immer)
function ENT:Draw() --ENT:Draw()
--Zeichnet das Modell
self:DrawModel()
--Zeichnet des Laser
render.SetMaterial(Material("sprites/bluelaser1"))
render.DrawBeam(self:LocalToWorld(Vector(0,0,120)), p2+Vector(0,0,50), 200, 1, 100, beam_color)
--Prüft ob der Laser sichtbar sein soll
if sbt == true then
beam_color = 255,0,0,255
beam_alpha = 255
sbt = false
end
--Reduziert langsam die Sichtbarkeit des Lasers
if sbt == false && beam_alpha > 0 then
if CurTime() > beam_fadetime then
beam_alpha = beam_alpha - 1
beam_color = Color(beam_alpha,0,0,beam_alpha)
beam_fadetime = CurTime() + 0.002
end
end
end
[/CODE]
init.lua
[CODE]--Sende die Dateien an den Client
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
--Binde die Dateien hier ein
include("sound.lua")
include("shared.lua")
--Läuft einmal beim spawnen
function ENT:Initialize()
--Definiere das Modell
self:SetModel("model/firepike/firepike.mdl")
self:PhysicsInit(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:SetSolid(SOLID_VPHYSICS)
--Prüfe ob Wiremod installiert ist und erstelle inputs
if (WireAddon) then
self.Inputs = WireLib.CreateInputs(self.Entity, {"Active [NORMAL]", "Entity [ENTITY]"})
end
--Weise dem Entity physikalische Eigenschaften zu und spawne es
local phys = self:GetPhysicsObject()
if phys:IsValid() then
phys:Wake()
phys:SetMass(500)
end
end
--Läuft einmal beim tatsächlichen Spawnen
function ENT:SpawnFunction(ply, tr) --ENT:SpawnFunction(ply, tr)
--Prüft ob firepike bereits existiert und verhindert einen 2. Spawn
for k,v in pairs(ents.GetAll()) do
if v:GetClass() == "firepike" then
print("Firepike: Bereits vorhanden!")
return
end
end
--Erstelle firepike und aktiviere es, weise HP und andere Eigenschaften zu
local ent = ents.Create("firepike")
ent:SetPos(tr.HitPos+Vector(0,0,20))
ent:Spawn()
ent:Activate()
ent:SetHealth(500)
undo.Create("firepike")
undo.AddEntity(ent)
undo.SetPlayer(ply)
undo.Finish()
end
--Läuft beim beschädigt werden und zieht HP von firepike ab bzw. zerstört es am Ende
function ENT:OnTakeDamage(info) --ENT:OnTakeDamage(info)
self:SetHealth(self:Health() - info:GetDamage())
if self:Health() <= 0 then
self:Remove()
end
end
--Wird beim entfernen von Firepike ausgeführt
function ENT:OnRemove() --ENT:OnRemove()
self:EmitSound("destroy")
self:Remove()
end
[/CODE]
shared.lua
[CODE]--Definiere das Entity
ENT.Type = "anim"
ENT.Base = "base_gmodentity"
ENT.PrintName= "FirePike"
ENT.Author= "vANTiiXSpike"
ENT.Contact= "Via steam"
ENT.Purpose= "Defense"
ENT.Instructions= "Creates a laser shooting tower."
ENT.Spawnable = true
ENT.AdminSpawnable = false
if SERVER then
--Definiere Basisvariablen
--Laser
local load_ray_delay = 0
local load_counter = 0
--Wiremod
local active = 1
local entity
--Definiere Netzwerkvariablen
util.AddNetworkString("DrawLaserA")
util.AddNetworkString("DrawLaserB")
util.AddNetworkString("drawbit")
--Läuft jederzeit
function ENT:Think() -- ENT:Think()
--Prüfe ob Wiremod installiert ist und lese Inputs
if (WireAddon) then
active = self.Inputs["Active"]
entity = self.Inputs["Entity"]
--Lies die Inputs aus
for k,v in pairs(active) do
if k == "Value" then
active = v
end
end
for k,v in pairs(entity) do
if k == "Value" then
entity = v
end
end
--Wenn firepike aktiv und und das ziel validiert ist
if active == 1 then
if entity:IsValid() then
--Prüfe Sichtlinie zwischen firepike und ziel
local tr = util.TraceHull({
start = self:LocalToWorld(Vector(0,0,120)),
endpos = entity:GetPos(),
maxs = Vector(16,16,71),
mins = Vector(-16,-16,0),
filter = self,
mask = MASK_SHOT_HULL
})
--Wenn das anvisierte Entity das sichtbare Entity ist, laden und schießen
if tr.Entity == entity then
load_ray(self, tr.Entity)
shoot_ray(self, tr.Entity)
end
end
end
end
end
--Spiele den Lasercharge-Sound alle 1,9 Sekunden ab
function load_ray(ENT, PLY)
if CurTime() > load_ray_delay then
ENT:EmitSound("test")
load_counter = load_counter + 1
load_ray_delay = CurTime() + 1.9
end
end
--Schiesse auf das Ziel wenn der Laser geladen wurde
function shoot_ray(ENT, PLY)
if load_counter == 2 then
load_counter = 0
ENT:EmitSound("test2")
PLY:EmitSound("hit")
--Erstelle Explosionsschaden am Ziel
util.BlastDamage(PLY, ENT, PLY:GetPos()+Vector(0,0,50), 100, 500)
--Sende dem Client die Koordinaten fürs Laser zeichnen
net.Start("DrawLaserB")
net.WriteVector(PLY:GetPos())
net.Broadcast()
--Sende startbefehl zum zeichnen
net.Start("drawbit")
net.WriteBool(true)
net.Broadcast()
end
end
end
if CLIENT then
end
[/CODE]
I'm looking forward to any suggestions for improvement :)
The problem is you are using locals for the beam parameters and entity. These will carry over to every entity instance. Instead, store the variables on the entity, like Ent.my_var
Thank you. I've changed the local's to ENT.my_something. Now the last spawned entity is drawing the beam.
Can you give me an example? My next problem is the access at this point:
[CODE]ENT.my_beam_alpha = 0
ENT.my_beam_color = Color(0,0,0,0)
ENT.my_beam_fadetime = 0
ENT.my_p2 = Vector(0,0,0)
ENT.my_sbt = false
local p2 = Vector(0,0,0)
local sbt = false
--Empfängt die Laser-Koordinaten und den startbefehl
net.Receive("DrawLaserB",
function()
p2 = net.ReadVector()
end
)
net.Receive("drawbit",
function()
sbt = net.ReadBool()
end
)
--Wird beim Darstellen des Entity ausgeführt (also immer)
function ENT:Draw() --ENT:Draw()
self.my_p2 = p2
self.my_sbt = sbt
--Zeichnet das Modell
self:DrawModel()[/CODE]
Can't access the entity in net.Receive.
You need to send the entity in your serverside net send. Also, don't add the variables with the global ENT -- that will still make it apply to all entities. You have to define the variables in the entity's Initialize method.
Sorry, you need to Log In to post a reply to this thread.