Datastream is stupid

Yes, I know, Datastream is outdated and stuff, but hell, nobody knows when GMod 13 is released and I don’t have a key.

So, I use this crap in a gamemode.

Apparently, serverside, I hook a datastream to a function.

[lua]datastream.Hook(“lc_doscallback”, LC.Inventory.OnDoSCallback)[/lua]

And the callback is silly.

[lua]
function LC.Inventory:OnDoSCallback(a, b, c, d, e)
print(a, b, c, d, e)
end
[/lua]

Now, according to the documentation, since all that crap is done serverside, the callback is supposed to be passed 5 arguments.

But, whenever I send some data to the server with datastream, the callback only gets 4 arguments. Player omitted. So it treats the callback as if it was done clientside.

My mind can’t comprehend this. I clearly include the file serverside, and the errors produced by this are blue in the console (derp).

So, what the fuck. I would greatly appreciate this if someone would give a hint.

Also, this is the function I include the file with.

[lua]function LC:IncludePrefixed(filepath)
local t = string.Explode("/", filepath)
local filename = t[#t]
local pref = string.sub(filename, 1, 3)
if pref == “sv_” and SERVER then
include(filepath)
elseif pref == “cl_” then
if SERVER then
AddCSLuaFile(filepath)
else
include(filepath)
end
elseif pref == “sh_” then
if SERVER then
include(filepath)
AddCSLuaFile(filepath)
else
include(filepath)
end
end
end[/lua]

The include is run serverside (init.lua)

It’s because of how you’re hooks set up, the first argument is passed to LC.Inventory, for example:

[lua]
local what = {}
function what:hi( a, b )

print( a, b, self )

end

what:hi( 1, 2 ) – output: 1, 2, table: 0x23cf710
what.hi( 1, 2 ) – output: 2, nil, 1[/lua]

If you change

[lua]function LC.Inventory:OnDoSCallback(a, b, c, d, e)[/lua]

to

[lua]function LC.Inventory.OnDoSCallback(a, b, c, d, e)[/lua]

it should work.

Hm, it didn’t work. Also, that (2, nil, 1) behaviour is quite weird, could you please point me to why it behaves like that?

But nonetheless, it didn’t solve the problem. Unfortunately. Thanks for pointing out this kind of behaviour to me.

EDIT: Oh wait, it did work. Hm. Weird. Thanks.

It’s to do with metatables, I think. For example:

[lua]
function GiveMoney( ply, amount )

ply.money = ply.money + amount

end

hook.Add( “PlayerInitialSpawn”, “asdf”, function( ply )

ply.money = 0
GiveMoney( ply, 500 )

end )
[/lua]

But we could do it another way:

[lua]
function _R.Player:GiveMoney( amount )

self.money = self.money + amount

end

hook.Add( “PlayerInitialSpawn”, “asdf”, function( ply )

ply.money = 0
ply:GiveMoney( 500 )

end )
[/lua]

I’m sure there’s some technical reason why the latter way is more widely used, but personally it just feels more “right” to do it that way, looks neater too.

Hm. But does it add some sort of weird argument or something? I are confused. 8-|

You should use Lua Classes for your inventory instead.

What do you mean?

This function is merely a way to allow an option callback be called serverside when a player uses an option on an item.

I’m saying in general, you should classes for your inventory, google it. If you still have trouble post back.

Yeah, using : to make a function implies there’s an object sense to it, so to make it easier, the first argument is always assumed as an instance of the object you declared it part of. You can access this object in the function with the variable “self”.

So really, in your case you could have also fixed your original problem by doing:

[lua]
print( self, a, b, c, d )
[/lua]

Here, self would represent the first argument passed to it, in this case it’s the player.

[editline]1st January 2012[/editline]

I think what zzaacckk is talking about is metatables, a lot of other programming languages have a very similar feature called a class.

Oh, metatables. Not worth going over the hassle.

It is worth it.

It is. They will make your code alot easier to read and write, here is a stripped down version of my inventory system, with an object for an Inventory and items with a small example at the bottom.

[lua]
local InventoryMeta = {};
InventoryMeta.__index = InventoryMeta;

function Inventory( _Player )
local inv = {};
setmetatable( inv, InventoryMeta );

inv._Owner =  _Player;
inv._Items = { };

return inv;

end

function InventoryMeta:getOwner( … )
return self._Owner;
end

function InventoryMeta:addItem( Item_I )
if( self._Items[ Item_I:getParsedName() ] == nil )then
self._Items[ Item_I:getParsedName() ] = 1;
else
self._Items[ Item_I:getParsedName() ] = self._Items[ Item_I:getParsedName() ] + 1;
end
end

function InventoryMeta:getItems( )
return self._Items;
end


local allItems = {};

ItemMeta = {};
ItemMeta.__index = ItemMeta;

function GetItem( _pN )
for a, b in pairs( allItems ) do
if(b:getParsedName() == _pN)then
return b;
end
end
end

function Item( _pN, _fN )
local it = {};
setmetatable( it, ItemMeta );

it._parsedName = _pN;
it._feasibleName = _fN;

allItems[ _pN ] = it;

return it;

end

function ItemMeta:getParsedName( … )
return (self._parsedName);
end

function ItemMeta:getFeasibleName( … )
return (self._feasibleName);
end


local exampleInventory = Inventory(“Zack”);

Item(“item_health_pack”, “First Aid Kit”);
Item(“item_car_hummer”, “Hummer”);

local Item_HP = GetItem(‘item_health_pack’);
local Item_Hummer = GetItem(‘item_car_hummer’);

exampleInventory:addItem(Item_HP);
exampleInventory:addItem(Item_Hummer);
exampleInventory:addItem(Item_Hummer);

for a,b in pairs( exampleInventory:getItems() ) do
print( exampleInventory:getOwner() … " has " … b … " " … a … “(s)” );
end
[/lua]

Rends



Zack has 1 item_health_pack(s)
Zack has 2 item_car_hummer(s)


Well, that really depends on how your inventory works.

I gave you an example of how you can do objects in lua, you can use it for almost any scenario your trying to accomplish. Take it or leave it, I am just trying to help you.

In Lua, i believe doing something like function variable:Name(argument) will ‘set’ argument inside the function the the variable behind :Name, so function _R.Player:Something is equal to _R.Player.Something=function(self). So argument a in “function LC.Inventory:OnDoSCallback(a, b, c, d, e)” will be LC.Inventory.