[*S*] Left click for spawn, works all the time

Started by Sebastian, Mar 28, 2015, 09:34 PM

Previous topic - Next topic

Sebastian

As we all know, the only moment when we can use left mouse button for spawn, is actually at our first spawn in a server.
Even if this is not a really good idea (to fix it by script), I'm showing you the easiest way to do it.
(until developers fix it in client)


The main idea is that we check if a player that is not yet spawned, binds left click. If it does press the button, we force it's spawn.
BIND_LEFT_MOUSE <- null;

function onScriptLoad()
{
BIND_LEFT_MOUSE = BindKey( true, 0x01, 0, 0 );
}

function onKeyDown( player, key )
{
if( key == BIND_LEFT_MOUSE && !player.IsSpawned ) player.Spawn( );
}

.

BUT (yes there's a BUT!), I'd like to raise a few questions. The player shoots with the mouse. Therefore, wouldn't that generate a massive amount of event calls on a full server? And, would the old shoot/spawn event still work if you bind this key? I'm just curious.
.

Sebastian

#2
Quote from: S.L.C on Mar 28, 2015, 09:41 PMThe player shoots with the mouse. Therefore, wouldn't that generate a massive amount of event calls on a full server?

Moving upper the if( !player.IsSpawned ) should reduce the lag that could be caused.

if( !player.IsSpawned && key == BIND_LEFT_MOUSE ) Message( "binded" ); player.Spawn( );

Quote from: S.L.C on Mar 28, 2015, 09:41 PMAnd, would the old shoot/spawn event still work if you bind this key? I'm just curious.

Yep, it still works.
player.Spawn( ) is calling the onPlayerSpawn event.
onPlayerActionChange is called when a player fires.

Btw, good questions. :)

.

#3
Quote from: sseebbyy on Mar 28, 2015, 10:11 PMMoving upper the if( !player.IsSpawned ) should reduce the lag that could be caused.

Actually not really. Let me explain what happens in the scripting plugin whenever there's keypress event:

You know that at the root of all things in your script there's one huge global table that holds the global elements. I.e. the root table. And the more you add to that table the more it takes to search for things.

Well, that table can get quite busy. Especially since all the script-writers use the <- instead of = and make all things global. Which is why I always insist on people to stop making all things global. To have an idea of how many things are in that global table use the following:
print( getroottable().len() );
Anyway, each time there's a server event, the Squirrel plugin looks for an element in that table with the name of the event. The following code illustrates that (should output "function"):
function onKeyDown(player, key)
{
    //...
}

print( typeof getroottable().rawget("onKeyDown") );

And if the found element is of type function. Remember that Squirrel is a dynamically typed language and every variable or table element can be anything. Anyway, if the found element is a function then it proceeds to calling it.

Calling that function involves a few more operations like pushing the function arguments onto a stack and then actually calling the function which pops the arguments from the stack. Not to mention the things you have to verify in the function like IsSpawned() which is another function call and the rest of the conditions etc. Which result in a ton of instructions to do on each event.

Don't get me wrong, your CPU isn't stupid and can take all of that. But if you start adding other events and other code then it starts to feel heavy. Not to mention that there's no filtering like in the plugin that I'm working on. So, you get a bunch of event calls that you'll ignore anyway.

But all that is just tl;dr and it's worthless. When I could simply have said: This shouldn't be done with scripts. Which comes to my proposal. Would it be ok if I made this as a C/C++ plugin  to be as fast as possible? And then post it here. Would take just a few minutes to make.
.

Sebastian

#4
Quote from: S.L.CBut all that is just tl;dr and it's worthless

Not really, I understood much part of what you said.
( didn't know about the roottable, and etc )



Unfortunately, I have no knowledge about C/C++ , so there is no way for me to write a plugin.
(if I knew how to, scripts like CMS would be as plugins, haha)

Quote from: S.L.CEspecially since all the script-writers use the <- instead of = and make all things global. Which is why I always insist on people to stop making all things global.

I updated the first script (should be better now), and I'm pretty sure I will practice what you said in my scripts.



Well, this is all I can do via scripts.
If you are going to write the plugin for it, would be great, and maybe developers will use it too, in the next update.

rObInX


.

Quote from: rObInX on Mar 28, 2015, 11:07 PMHe meant not to use <-

It's ok to use that with keybinds because you can't create more keybinds for the same key. And therefore making it global would allow others to use that keybind.
.

Sebastian

I still have doubts about the difference between these two ways I have used:

  • making it global by directly giving the value
  • making it global by giving null value, then giving the wanted value onScriptLoad

I have seen that in stormeus' released script (the one used in last pb):
BIND_HYDRAULICS_LEFT  <- null;

function onScriptLoad( )
{
     BIND_HYDRAULICS_LEFT  = BindKey( true, 0x64, 0, 0 );
}

I concluded that doing it like this, will not help in making more busy the root table, because I think the null values won't be counted until it is used.

But I can be wrong, so what's the difference between these 2 ways ?

vcmptr

My English is not good.

.

Quote from: sseebbyy on Mar 28, 2015, 11:26 PMbecause I think the null values won't be counted until it is used.

Actually NO! Let me give an example and imagine that my_table is the root/global table (because it's the same):
local my_table = {}; // Empty root table

print(my_table.len()) // Should be 0

my_table.my_element <- null;

print(my_table.len()) // Should be 1

It doesn't matter if an element is null or not. Believe it or not, but null, is also a type of data. Once you create an element in that table then it stays there until you explicitly remove it. So I could do:
my_global_variable <- "wazzaaaa";

print( getroottable().my_global_variable ) // You should see: wazzaaaa
print( getroottable()["my_global_variable"] ) // You should see: wazzaaaa
print( getroottable().rawget("my_global_variable") ) // You should see: wazzaaaa

getroottable().rawdelete("my_global_variable");

print( getroottable().my_global_variable ) // That index doesn't exist anymore
print( getroottable()["my_global_variable"] ) // That index doesn't exist anymore
print( getroottable().rawget("my_global_variable") ) // That index doesn't exist anymore

The reason he creates them as null and then initializes them in OnLoad() is because the plugin API isn't initialized at that time. And if you call any of it's functions then your server will crash. At least that's how it used to be. Now the scripts are executed when the server calls OnInit() and the plugin API is already initialized. Probably just a habit from before.

But the actual reason I think is because it allows him to know what global variables are available. Because using <- silently in a function can stay unnoticed until you make another one with the same name. And when that happens you overwrite the first one and things could go bad. Which is another good example of why <- should be avoided in the root/global table.
.

Sebastian

Things are now much clear. Mulțumesc. 8)

Gulk

#11
Good idea, ill add it to my server.
Someone joined yesterday and quit everytime they died to rejoin, knew they had the bug and didn't speak English so I couldn't help.
 :edit: O0 O0

Sk

Quote from: Gulk on Mar 29, 2015, 07:22 AMGood idea, ill add it to my server.
Someone joined yesterday and quit everytime they died to rejoin, knew they had the bug and didn't speak English so I couldn't help.
 :edit: O0 O0
hhhhh
sorry it was me i was testing some key shortcut to /q when i press that button (to death evade ofc :<).
i wanted to join again but no battery left (in laptop) for that.
p.s i do know how to speak english a lil bit.

aXXo

Quote from: S.L.C on Mar 28, 2015, 09:41 PMThe player shoots with the mouse. Therefore, wouldn't that generate a massive amount of event calls on a full server?
You mentioned the shoot key in specific. Does the event get called when a player presses any key, irrespective if it has a binding or not?
Think of 30 hotheads smashing their keyboard and mouse in an intense battle. Does that call onKeyDown(player, null) and  onKeyUp(player, null) on every key press?

.

#14
Quote from: aXXo on Mar 29, 2015, 02:37 PMThink of 30 hotheads smashing their keyboard and mouse in an intense battle. Does that call onKeyDown(player, null) and  onKeyUp(player, null) on every key press?

Yes, as long as a key is binded you'll receive a call through that function. Even if you don't need that event sometimes.
.