• Problem with ents.create and a table.
    10 replies, posted
Before I tell you my problem, here's the code. [lua] for k, v in pairs(self.Entity.Contents) do local vclass = v:GetClass() local vmodel = v:GetModel() if !v:IsValid() then return end local vspawn = ents.Create(vclass) vspawn:SetPos(self:GetPos()) vspawn:SetModel(vmodel) vspawn:Spawn() vspawn:Activate() end table.Empty(self.Entity.Contents) [/lua] As you can see for each entity/weapon in the table it spawns it and empties the table. I cannot understand why but what it does is spawn two values (entities) instead of one even if there's only one in the table. I put two of the same entities into the table, it generates four. And so on. Any ideas? [editline]30th September 2013[/editline] Also, if I press E on the other entity it spawns then it throws this error: [code]bad argument #1 to 'Create' (string expected, got nil) [/code]
vclass is nil. Means v:GetClass() doesn't return anything. Post contents of your table.
The contents are dynamic, it's a box. You grav gun entities in, it keeps them untill destroyed or taken out using a VGUI. I don't understand though, how can vclass be nil if it does spawn the correct weapon/entity?
I assume this is called from ENT:Use? If so, you must put self:SetUseType(SIMPLE_USE) in your ENT:Initialize My upper post is about the error only.
There are two ways to get the entities out, one is using it (ENT:Use) and the other is destroying the box. Using it opens the VGUI and I can spawn the weapon/entities just fine. But if I destroy the box, it executes the code in OP and works. The problem is that while it does work, even if the table contains only one entry (entity/value/whatever) it duplicates it and spawns 2 entities. Basically, destroy crate with one weapon in it, code in op gets executed, creates two weapons instead of one. One weapon is use-able, second weapon throws the error in the OP. (the second weapon shouldn't even spawn)
First of all move if !v:IsValid() then return end up so it looks like this: ( I also recommend using IsValid(ent), not ent:IsValid() ) [code] for k, v in pairs(self.Entity.Contents) do if !IsValid(v) then break end local vclass = v:GetClass() local vmodel = v:GetModel() local vspawn = ents.Create(vclass) vspawn:SetPos(self:GetPos()) vspawn:SetModel(vmodel) vspawn:Spawn() vspawn:Activate() end table.Empty(self.Entity.Contents)[/code] "return end" might have prevented table.Empty from being called, and something else might have called the code twice, so we change it to "break end" which only breaks the loop and continues to run the code after it.
[video=youtube;JmUSOBSm4kc]http://www.youtube.com/watch?v=JmUSOBSm4kc[/video] Sorry for the shit quality. Your code didn't change a thing sadly, and yeah thanks for the IsValid tip.
Show the whole entity code.
[lua] if CLIENT then function ENT:Initialize() end list.Set("SpawnableEntities", "npc_grenade_frag", { PrintName = "Frag Grenade", ClassName = "npc_grenade_frag", Category = Category, DropToFloor = true, Author = "VALVe", AdminOnly = false }) function ENT:Draw() self.Entity:DrawModel() local contents = self.Entity:GetNWInt("HowManyInBox") local pos = (self.Entity:GetPos() + self.Entity:GetAngles():Up()*40):ToScreen() local x = pos.x local y = pos.y x = x - string.len(contents.."/"..self:GetNWInt("callowed"))*1.5 - 12 local angs = self.Entity:GetAngles() angs:RotateAroundAxis(angs:Forward(), 90) cam.Start3D2D(self.Entity:GetPos() + self.Entity:GetAngles():Right()*20.5,angs,0.5) if self:GetNWInt("callowed") == 4 and contents >=3 then draw.WordBox(6, 0 - string.len(contents.."/"..self:GetNWInt("callowed"))*1.5 - 17, -34, contents.."/"..self:GetNWInt("callowed"), "TargetID",Color(100,100,100,0),Color(255,0,0,255)) elseif self:GetNWInt("callowed") == 6 and contents >=5 then draw.WordBox(6, 0 - string.len(contents.."/"..self:GetNWInt("callowed"))*1.5 - 17, -34, contents.."/"..self:GetNWInt("callowed"), "TargetID",Color(100,100,100,0),Color(255,0,0,255)) elseif self:GetNWInt("callowed") == 6 and contents < 5 then draw.WordBox(6, 0 - string.len(contents.."/"..self:GetNWInt("callowed"))*1.5 - 17, -34, contents.."/"..self:GetNWInt("callowed"), "TargetID",Color(100,100,100,0),Color(255,225,0,255)) else draw.WordBox(6, 0 - string.len(contents.."/"..self:GetNWInt("callowed"))*1.5 - 17, -34, contents.."/"..self:GetNWInt("callowed"), "TargetID",Color(100,100,100,0),Color(0,255,255,255)) end cam.End3D2D() end net.Receive("forsaken_crateopen", function(len) local my_table = net.ReadTable() local CrateEnt = net.ReadEntity() local DermaPanel = vgui.Create( "DFrame" ) local Pos = Vector(ScrW()/2 + 1,ScrH()/2 + 1) DermaPanel:SetSize( 555 + 5*2, 310 + 25*2 ) DermaPanel:SetTitle( "Crate" ) DermaPanel:SetVisible( true ) DermaPanel:SetPos( ScrW() / 2 - 320, ScrH() / 2 - 180) DermaPanel:SetDraggable( true ) DermaPanel:ShowCloseButton( true ) DermaPanel:MakePopup() DermaPanel.Paint = function() draw.RoundedBox( 8, 0, 0, DermaPanel:GetWide(), DermaPanel:GetTall(), Color( 0, 0, 0, 150 )) end local BG = vgui.Create( "DImage",DermaPanel) BG:SetPos(5, 25) BG.Paint = function() draw.RoundedBox( 8, 0, 0, BG:GetWide(), BG:GetTall(), Color( 0, 0, 0, 200 )) end BG:SetSize( 555, 328 ) -- Set the size of the panel local Scroll = vgui.Create( "DScrollPanel", DermaPanel ) //Create the Scroll panel Scroll:SetSize( 550, 300 ) Scroll:SetPos( 10, 30 ) Scroll:SetBGColor(255,255,0,255) Scroll:SetPaintBackgroundEnabled(true) local List = vgui.Create( "DIconLayout", Scroll ) //Create the DIconLayout and put it inside of the Scroll Panel. List:SetSize( 550, 300 ) List:SetPos( 0, 0 ) List:SetSpaceY( 5 ) //Sets the space inbetween the panels on the X Axis by 5 List:SetSpaceX( 5 ) //Sets the space inbetween the panels on the Y Axis by 5 List:SetBGColor(255,255,0,255) List:SetPaintBackgroundEnabled(true) for k,v in pairs(my_table) do local icon = List:Add("SpawnIcon", button) icon:SetModel(v:GetModel()) icon:SetTooltip(v:GetClass()) icon.DoClick = function() net.Start("forsaken_cratespawn") net.WriteEntity(CrateEnt) net.WriteFloat(k) net.SendToServer() DermaPanel:Close() end end DermaPanel:SizeToContents() end) end function ENT:SpawnFunction( Player, Trace ) if ( !Trace.Hit ) then return end local SpawnPos = Trace.HitPos + ( Trace.HitNormal * 32 ); local Entity = ents.Create( "forsaken_crate" ); Entity:SetPos( SpawnPos ); Entity:Spawn(); Entity:Activate(); return Entity; end if SERVER then util.AddNetworkString("forsaken_crateopen") util.AddNetworkString("forsaken_cratespawn") AddCSLuaFile("forsaken_crate.lua") ENT.Contents = {} net.Receive("forsaken_cratespawn", function(len,ply) local Crate = net.ReadEntity() local indx = net.ReadFloat() local Ent = Crate.Contents[indx] Ent:GetPhysicsObject():EnableMotion(false) table.remove(Crate.Contents,indx) constraint.RemoveAll(Ent) Ent:SetPos(Crate:GetPos() + Vector(0,0,30)) Ent:SetGravity(1) Ent:GetPhysicsObject():EnableMotion(true) net.Start("forsaken_crateopen") net.WriteTable(Crate.Contents) net.WriteEntity(Crate) net.Send(ply) end) function ENT:Initialize() self.Entity.Contents = {} self.Entity:SetModel("models/props_junk/wood_crate001a.mdl") self.Entity:PhysicsInit(SOLID_VPHYSICS) self.Entity:SetMoveType(MOVETYPE_VPHYSICS) self.Entity:SetSolid(SOLID_VPHYSICS) self.Entity:SetUseType(SIMPLE_USE) self:SetNWInt("callowed", 4) self.damage = 100 local phys = self.Entity:GetPhysicsObject() if phys and phys:IsValid() then phys:Wake() end end function ENT:Use(ply) if ply:IsValid() and ply:IsPlayer() then net.Start("forsaken_crateopen") net.WriteTable(self.Entity.Contents) net.WriteEntity(self.Entity) net.Send(ply) end end function ENT:OnTakeDamage(dmg) self:TakePhysicsDamage(dmg) if(self.damage <= 0) then return end self.damage = self.damage - dmg:GetDamage() if 0 > self.damage then self:GibBreakServer(Vector(10, 10, 10)) for k, v in pairs(self.Entity.Contents) do if !IsValid(v) then break end local vclass = v:GetClass() local vmodel = v:GetModel() local vspawn = ents.Create(vclass) vspawn:SetPos(self:GetPos()) vspawn:SetModel(vmodel) vspawn:Spawn() vspawn:Activate() end table.Empty(self.Entity.Contents) self:Remove() end end function ENT:Think() local weight = 30 self.Entity:SetNWInt("HowManyInBox",#self.Entity.Contents) for k,v in pairs(self.Entity.Contents) do if !v:IsValid() then table.remove(self.Entity.Contents, k) else weight = weight + v:GetPhysicsObject():GetMass() v:NextThink( CurTime() + 1 ) if v:GetPos():Distance(self.Entity:GetPos()) > 10 then v:SetPos(self.Entity:GetPos()) for _,ENT in pairs(self.Entity.Contents) do constraint.NoCollide(ENT,v,0,0) end constraint.Weld(v,self.Entity,0,0,0,true) DropEntityIfHeld(v) end end end self.Entity:GetPhysicsObject():SetMass(weight + 50) end function ENT:PhysicsCollide(data, physobj) local ent = data.HitEntity if ent.IsCharge then self:SetNWInt("callowed", 8) ent:Remove() end if ent:IsValid() and !ent:IsWorld() and !ent.IsMoneyPrinter and !ent.IsCharge then if ent:GetNWBool("CanBePlaced") and ent:BoundingRadius() < 25 and #self.Entity.Contents < 4 then MsgN(ent:BoundingRadius()) table.insert(self.Entity.Contents, ent) ent:SetNWBool("CanBePlaced", false) ent:SetPos(self.Entity:GetPos()) ent:SetNWEntity("CrateEnt", self.Entity) for k,v in pairs(self.Entity.Contents) do constraint.NoCollide(v,ent,0,0) end constraint.Weld(ent,self.Entity,0,0,0,true) DropEntityIfHeld(ent) end end end hook.Remove("GravGunOnPickedUp", "1944MakeObjectPlaceableInCrate",function(pl, ent) if pl:IsValid() and ent:IsValid() then ent:SetNWBool("CanBePlaced", true) end end) hook.Add("GravGunOnDropped", "UnMakeObjectPlaceableInCrate",function(pl, ent) if pl:IsValid() and ent:IsValid() then ent:SetNWBool("CanBePlaced", false) end end) hook.Add("GravGunPickupAllowed", "1944MakeObjectPlaceableInCrate",function(pl, ent) if pl:IsValid() and ent:IsValid() then local IsInCrate = ent:GetNWBool("IsInCrate") if !IsInCrate then ent:SetNWBool("CanBePlaced", true) else return false end end end) timer.Create("CheckIfEntIsInCrate",1,0,function() for k,v in pairs(ents.GetAll()) do v:SetNetworkedBool("IsInCrate",false) for _,ent in pairs(ents.FindByClass("forsaken_crate"))do if table.HasValue(ent.Contents,v) then v:SetNetworkedBool("IsInCrate",true) end end end end) hook.Add("EntityTakeDamage","DamageCrate",function(ent, dmginfo) if ent:GetNWBool("IsInCrate") then dmginfo:ScaleDamage(0) end end) end ENT.Type = "anim" ENT.Base = "base_gmodentity" ENT.PrintName = "Storage Crate" ENT.Author = "Scarness" ENT.Spawnable = true ENT.AdminSpawnable = false[/lua]
-snip- [editline]30th September 2013[/editline] You don't remove the weapons that are inside the box and you spawn new ones.
Oh man I completely forgot about that. Thanks!
Sorry, you need to Log In to post a reply to this thread.